이미지 최적화를 위한 WebP 포맷 적용 이야기

레진코믹스는 다양한 웹툰을 글로벌 서비스하고 있는 회사입니다. 저희 개발구성원들은 항상 더 빠르고 안정적인 서비스를 하기 위해 각자 맡은 영역에서 최선을 다하고 있습니다. 그 노력의 일환으로 백엔드 관점에서 차세대 포맷인 WebP를 적용하면서 겪었던 경험담을 공유하려 합니다.

WebP 란 무엇인가?

2010년 구글이 만든 이미지 포맷으로 홈페이지에서 JPEG(손실)나 PNG(비손실) 포맷대비 30% 정도 더 사이즈가 작다고 설명하고 있습니다.

WebP를 지원하는 브라우저

  • Google Chrome (desktop) 17+
  • Google Chrome for Android version 25+
  • Microsoft Edge 18+
  • Firefox 65+
  • Opera 11.10+
  • Native web browser, Android 4.0+ (ICS)

현재는 Safari에서 지원하지 않습니다만(앞으로도 안될거 같아요..) 그럼에도 불구하고 웹서비스 최적화 권고시 빠지지 않고 등장하다 보니 WebP 포맷을 채택한 서비스가 점점 더 늘어나고 있습니다.

이미지 서버 아키텍쳐

저희 레진 코믹스에서 운영 중인 이미지 서버는 파이썬으로 개발되어 있고, 업로드 서버와 서비스용 서버 2종류가 있습니다.

이미지 업로드 서버 아키텍쳐

업로드 서버는 백오피스에서 작품을 업로드 하거나 대량으로 작품을 업로드 하는 경우 요청을 받아서 이미지 리사이징 후 S3 버킷에 업로드 합니다. 이미지 업로드 작업 수행시 원본 이미지를 기준으로 미리 정해놓은 해상도별 이미지로 리사이징 하는 작업이 수행되게 되는데 이 작업은 오래걸리는 작업이므로 Celery를 사용하여 비동기 태스크로 동작합니다.

서비스용 이미지 서버 아키텍쳐

여기선 CDN과 이미지 서버의 역할이 나뉘게 되는데요 CDN의 역할은 아래와 같습니다.

  • 사용자가 이미지를 요청하면 해당 사용자에게 가장 가까운 CDN 엣지 로케이션으로 요청하고 이미지 캐시 여부를 판단함
  • CDN에 캐시된 이미지는 이미지별로 다르지만 일반적으로 100ms 안쪽으로 응답함
  • 최초 요청이라면 CDN에선 이미지 서버를 요청하여 이미지 서버로 부터 응답 받은 이미지를 캐시한다.

서비스 이미지 서버의 역할은 아래와 같습니다.

  • 이미지 요청을 분석하여 프리셋이 존재하는지 체크하여 존재한다면 S3에서 가져온뒤 응답
  • 간혹 프리셋이 존재하지 않는 경우 동적으로 프리셋을 생성하여 S3에 업로드합니다. 이 작업 역시 Celery를 사용하여 비동기 태스크로 동작합니다.
  • 배너의 경우 원본이미지를 기준으로 온디맨드 리사이징처리 하여 응답합니다.

처음엔 온디맨드 방식으로 개발

그 동안 배너를 제외한 웹툰 컨텐츠의 경우 각 에피소드의 컷별로 해상도, 퀄리티를 구분하여 프리셋을 만들고 있었습니다. 그러다보니 S3 인프라 운영 비용도 점점 증가하는 추세였고, 또 WebP를 적용하게 되면 기존의 해상도별 프리셋 이미지엔 WebP가 존재하지 않다보니 마이그레이션을 해야하는 이슈도 있어서 WebP포맷에 대해선 온디맨드 방식으로 컨버팅과 리사이징을 하는 전략으로 개발하게 됩니다.

이 전략은 다른 서비스에도 많이 적용된 검증된 방식이고 이미지 서버 앞단에 CDN이 있으므로 엣지별로 최초 요청만 느리고 그 이후엔 캐시되어 빠르게 응답할것이라 확신하여 개발 완료와 동시에 테스트를 진행하였습니다.

온디맨드 처리와 프리셋 업로드 처리 방식을 같이 사용

테스트 시 발견된 문제점은 서버 사양을 감안하더라도 원본 JPEG에서 WebP 포맷 컨버팅과 리사이징 속도가 생각 이상으로 오래 걸린다는 것이었습니다. 이 부분은 CPU의 연산속도에 따라 차이가 커서 사양을 올리고 이미지 라이브러리 업데이트로 효과를 볼 순 있었습니다만 한 가지 간과한 것이 있었는데, 그건 바로 저희가 고퀄리티 웹툰 이미지를 서비스한다는 것이었습니다.

배너나 썸네일 같이 파일 사이즈가 작고 디자인에 따라 해상도가 달라지는 이미지의 경우엔 온디맨드 리사이징 전략을 사용하는 것이 유리하지만, 저희 웹툰 이미지들은 작가분들께서 정성스레 작업 한 고퀄리티 이미지들이기 때문에 기본 이미지 사이즈도 큰편이고 디바이스별로 최적화된 프리셋도 다양하게 준비되어 있어 웹툰 이미지를 온디맨드 방식으로 운영하는데에 따른 부담이 있었습니다.

또한 미국과 유럽 등 해외에서도 레진 코믹스가 사랑받다 보니 세계 각국에서 CDN의 다양한 엣지로 접근을 하게 됩니다. 이 때문에 모든 이미지를 온디맨드 방식으로 처리하게 되면 cache miss된 이미지가 많을 수밖에 없고 오히려 온디맨드 방식이 더 나쁜 사용자 경험을 제공할 것이라 판단이 되어 배너를 제외한 웹툰 이미지는 업로드 방식으로 재개발하였습니다.

변경된 처리 방식은 아래와 같습니다.

  • 신규 이미지 업로드시 JPEG과 마찬가지로 WebP 포맷으로 리사이징된 프리셋도 S3에 업로드
  • 이미 JPEG으로 서비스 되고 있는 이미지는 .webp로 첫 요청시 온디맨드로 WebP 리사이징하여 응답함과 동시에 비동기적으로 프리셋을 S3에 업로드

위의 방식으로 재개발한 뒤 개발그룹에서 가장 고생하고 계신 Devops 팀의 도움을 받아 점진적으로 배포를 완료하게 되었습니다.

적용 결과 비교

JPG로 요청시

WebP로 요청시

이미지 마다 다르지만 실제로 평균 30% 전후로 파일 사이즈가 작아진걸 확인 할 수 있었습니다.

회고

WebP를 이미지 서버에 적용하면서 다른 서비스들에 적용된 방식이 우리 서비스에서도 잘 맞을 거라는 보장은 없다 는 것을 몸소 깨닫게 되었습니다. 이런 경험은 개발전에 리서치를 하고 사전에 관련 지식과 전략을 수립했음에도 불구하고 직접 경험해 보지 못하면 알 수가 없는 것이기 때문에 백엔드 개발자로써 레진 코믹스에서 대용량 서비스 경험을 하며 많은 것들을 배운 것 같습니다.

인프라 비용의 측면에선 온디맨드 리사이징과 프리셋 업로드 방식을 혼용하여 사용하게 됨으로써 S3 비용과 CPU 연산 비용은 증가하지만 반대로 트래픽 비용이 절감되고 사용자 경험이 좋아지기 때문에 긍정적인 Trade-off라고 생각합니다.

참고