현재 회사에서 운영하는 서비스에서는 유저가 원하는 사진파일을 활용해 이벤트 썸네일, 유저 프로필 사진 등으로 사용할 수 있다.
이 때, 유저의 사진파일을 저장하고 요청 시에 불러올 수 있도록 AWS의 S3를 활용하여 해당 기능들을 구현했다.
1. 어떻게 구현한 코드가 업로드 속도가 느렸는지
AWS SDK를 이용해 S3와 connection 후, 유저가 업로드할 파일의 buffer를 upload 옵션에 맞게 S3에 업로드하는 간단한 코드다.
여기에서 파일의 용량을 압축시켜 S3 bucket의 가용 용량을 확보하고, 페이지 로드 시 빠르게 이미지를 업로드할 수 있는 장점을 취하기 위해 webp로 변환하는 convertToWebp 함수를 작성해 사용하였다.
해당 코드를 file.module에 작성해놓고, 이벤트의 썸네일을 설정할 때와, 변경할 때 사용하였다.
그러나, convertToWebp 함수의 실행시간이 길어졌고, 유저는 파일이 webp로 변환되고, 변환된 파일을 S3에 업로드 할 때 까지 약 10초에 가까운 시간동안 로딩화면을 보게 되는 끔찍한 유저경험을 하게 되었다.
2. 이유는 무엇이었는지
결론적으로는, WebP에 대한 이해없이 WebP 변환을 했고, 그에 따라 10초 동안의 시간에서 WebP 변환하는 시간이 9.6초로 대부분을 차지 하게 되었다.
이후 수정된 코드는 단순하지만, PNG, JPG, WebP에 대한 이해와 비손실, 손실방식에 대한 차이를 알고, 이 두 가지 방식을 어떤 상황에서 사용해야하는지에 대한 판단근거와 디버깅 과정의 경험이 중요하다고 생각하여 조금 자세하게 글을 정리해보려고 한다.
WEBP
WebP란, 보통 인터넷에서 많이 쓰이는 GIF, PNG, JPG 포맷을 대체하기 위해 구글에서 개발된 파일 포맷이다. 우리가 흔히 봐왔던 PNG와 JPG는 각각, 비손실 방식과 손실 방식으로 대표되는 파일 포맷이다.
이 때, 등장하는 비손실 방식은 말 그대로 사진 파일의 퀄리티를 손상시키지 않는 포맷 저장 방식이고, 손실 방식은 사진 파일의 퀄리티를 손상시켜 용량을 줄이는 포맷 저장 방식이다.
비손실 방식과 손실 방식 두 방식 모두, 이미지 품질이 같을 때 WebP 파일의 크기가 다른 포맷의 파일에 비해 훨씬 작다.
예를 들어, WebP 파일의 크기는 같은 내용의 JPG 파일보다 25~34%, PNG 파일보다 26%(손실 압축을 사용하면 60~70%) 작다.
또, 손실 방식이라고 하여도 실제적으로 눈으로 보이는 부분은 큰 차이가 없기 때문에 (파일에 따라 다르지만 50~70%의 퀄리티에서는 큰 차이를 느끼지 못하는 정도), 용도에 맞게 비손실 방식과 손실 방식을 잘 선택하여 파일 저장 방식을 달리할 수 있다.
예를 들어, 컴퓨터 그래픽이나 문서 화면 캡쳐 등 원본을 그대로 유지해야 하는 파일은 비손실 방식을 사용하고, 실사 이미지나 게임 화면 같은 파일은 손실 방식을 선택하여 저장하는 것이 더 좋은 것으로 알려져있다.
아래는 같은 사진 파일을 90% 퀄리티 변환부터, 10% 퀄리티로 webp 변환한 사진인데 사실 육안으로 볼 때, 90~50% 까지는 차이를 크게 체감하지 못하지만 용량은 크게 줄일 수 있다.
이러한 WebP 파일의 특징과 장,단점을 파악하지 못한 채로 좋은 화질의 이미지 파일을 유저에게 제공함과 동시에 용량도 줄이고 싶은 마음에 이미지 파일의 용도에 맞지 않는 압축 방식을 선택했고, 결과적으로는 쓸 데 없는 시간을 WebP 변환에 사용하게 되었다.
3. 그래서 어떻게 수정하였는지
우리 서비스는 웹뷰 개발로, 결국엔 모바일 최적화가 더 우선적인 서비스이다. 이 때, 파일의 업로드 방식은 모바일에서 바로 찍어 업로드하는 경우와, 본인이 찍어둔 사진들로 업로드 하는 경우가 많다고 판단되어 손실 방식을 선택했다.
간단한 변경으로 s3 업로드를 포함한 event의 썸네일을 변경하는데 0.293초로 기존 loseless 방식 대비 약 33배의 속도개선을 이뤄냈다.
사실, 별 거 아닌 변화지만 많은 프로젝트에서 파일을 다루고 있고, 앞으로도 파일을 다루는 일이 많을 것이기에 이번 기회로 이미지 파일의 확장자에 따른 압축방식 및 용도를 알 수 있어서 좋은 경험이었다고 생각한다.
'Experience' 카테고리의 다른 글
코딩 금쪽이의 첫 리팩토링 후기(DB편) (2) | 2023.02.18 |
---|---|
RESTful API (0) | 2023.02.03 |
[SQL] RAND / OFFSET & LIMIT / alias (0) | 2023.02.03 |