비대면 러닝 챌린지 서비스를 리팩토링하면서 WEBP로 파일 형식을 변경하여 이미지 파일 크기 문제를 해결하고 빌드 속도를 약 35% 개선, 앱 크기를 소폭 줄여냈습니다.
문제 발생
서버로 이미지를 업로드하는 API 요청에서 HTTP 413 Request Entity Too Large 에러가 발생하는 문제가 있었습니다. 이 에러는 서버에 허용하는 요청 엔티티 크기를 초과할 때 발생합니다. 이 에러로 이미지의 파일 크기에 대해 고려해보게 되었습니다.
고민점
1. 서버 허용량 늘리기
현재 서비스에서 사용되는 이미지들은 해상도가 크게 중요하지 않다고 생각해서 서버의 허용량은 조금만 늘리고 이미지 파일 크기를 최대한 줄여야겠다고 생각했습니다. (현재 클라우드 지원으로 무료로 네이버 클라우드 플랫폼을 사용하고 있지만 지원이 언제 끊길 지 모르기 때문에 비용을 최대한 아끼자는 생각도 함께 했습니다.)
2. 파일 형식 변경
파일 형식에 따라 크기 차이가 있다는 것을 봤던 기억이 떠올라 파일 형식의 특징에 대해 살펴보게 되었습니다. 이미지 파일을 압축하면서 사용하는 Bitmap의 CompressFormat에는 PNG, JPEG, WEBP 형식만 존재했기 때문에 이 형식에 대해서만 알아보았습니다.
파일 형식 비교
JPEG vs PNG
다들 JPEG와 PNG 파일 형식은 많이 들어보셨을 거라 생각합니다. 가장 보편적으로 사용되는 파일 형식으로 JPEG는 디지털 사진에 많이 사용되고 PNG는 웹 그래픽 용으로 많이 사용됩니다. 다른 특징들은 생략하고 파일 크기, 압축 방식에 대해 설명드리겠습니다.
JPEG와 PNG는 다른 압축 프로세스를 가지고 있습니다. JPEG는 손실 압축, PNG는 무손실 압축 형식입니다. JPEG는 말 그대로 압축 시에 데이터가 손실됩니다. 파일을 압축할 때 이미지의 일부 데이터가 손실되기 때문에 이미지가 손상되고 화질이 안좋아질 수 있습니다. PNG는 무손실 압축 방식으로 압축될 때 손실되는 데이터가 없습니다. 같은 퀄리티로 압축을 하게 된다면 JPEG는 손실이 되기 때문에 압축 시에 더 적은 파일 크기를 갖게 됩니다.
저희 서비스에는 PNG보다는 파일 크기를 최대한 줄이는 JPEG가 더 적합하다고 생각하게 되었습니다.
WEBP
WebP는 Google에서 제공하는 이미지 파일 형식으로, 손실이 있는 압축(예: JPEG)과 투명도(예: PNG)를 제공하지만 JPEG나 PNG보더 더 나은 압축을 제공할 수 있습니다. 손실이 있는 WebP 이미지는 Android 4.0(API 수준 14) 이상에서 지원되며 손실이 없고 투명한 WebP 이미지는 Android 4.3(API 수준 18) 이상에서 지원됩니다. 이 페이지에서는 이미지를 WebP 형식으로 변환하는 방법과 WebP 이미지를 PNG 형식으로 변환하는 방법을 보여줍니다.
WEBP 형식은 안드로이드 공식 문서에 위와 같이 설명되어 있습니다. JPEG와 PNG보다 더 낫다는 설명인데 왜 JPEG와 PNG를 많이 쓰는 지 궁금했습니다.
WEBP 형식은 일부 브라우저 등에서는 지원이 안될 수 있다는 가장 큰 단점을 가지고 있었습니다. 특히 많이 사용하는 IOS에서도 버전 14부터, mac OS에서는 11부터 지원된다고 합니다.
IOS 버전 사용량을 살펴보니 16 버전을 90% 이상이 사용하고 있다고 하니 문제가 없을 듯 하지만 Safari에서는 정지 된 이미지만 보인다고 합니다.
하지만 저희 서비스에는 아직 ios를 지원하지 않고 있고 나중에 개발하게 된더라도 Gif를 사용할 가능성이 아주 적다고 생각하여 WEBP를 사용해도 괜찮다고 생각했습니다.
압축 시 파일 크기 비교
동일한 사진을 JPEG, PNG 그리고 무손실 압축 방식인 WEBP_LOSSLESS, 손실 압축 방식인 WEBP_LOSSY 모두 사용해보면서 압축 시에 파일 크기가 얼마나 차이나는 지 비교해보았습니다.
결과
PNG : 1216382
JPEG : 43759
WEBP_LOSSLESS : 1006158
WEBP_LOSSY : 27094
같은 무손실 압축 방식인 PNG와 비교해보아도 WEBP가 더 압축 효과가 좋고, 손실 압축인 JPEG와 비교해도 압축 효과가 좋다는 것을 확인할 수 있었습니다.
그렇기 때문에 가장 파일 크기가 적은 WEBP_LOSSY 로 파일 형식을 변경하게 되었습니다.
빌드 속도 향상, 앱 크기 줄이기
https://developer.android.com/topic/performance/reduce-apk-size?hl=ko
앱 크기 줄이기
https://developer.android.com/studio/build/optimize-your-build?hl=ko
빌드 속도 최적화
위 공식 문서를 살펴보면 WEBP 사용에 대한 설명이 있습니다. 현재 사용중인 drawable 리소스들을 WEBP로 변경해보면서 차이를 비교해보았습니다.
변경 전
변경 전의 빌드 속도는 62.0s, 그리고 apk의 크기는 118,778KB 입니다.
변경 후
drawable 폴더에 마우스 우클릭을 하면 Convert to WebP 메뉴가 존재하고 이를 통해 한 번에 WebP 파일로 변경할 수 있습니다. 압축율도 설정할 수 있는데 기본 default로 설정되어있는 75%로 압축하여 변경하게 했습니다.
압축 후 사진 해상도 변화
변경 후에는 변경 전 빌드 속도인 62.0s 보다 21.7s 빨라진 40.3s
apk 크기는 118,778KB에서 107,775KB 로 개선된 것을 확인할 수 있습니다.
apk 크기는 많이 개선되지 않았지만 빌드 속도는 정말 유의미하게 개선된 것을 확인할 수 있습니다.
'Android 일지 > 리팩토링' 카테고리의 다른 글
직접 문제를 겪고 작성한 Flow asResult 확장 함수 (0) | 2023.11.06 |
---|---|
3. 경로 최적화로 좌표 데이터 약 73% 감소 (2) | 2023.10.17 |
6. SharedPreference에서 DataStore로 변경하여 데이터 일관성 문제 해결하기 (0) | 2023.05.30 |
5. CustomView로 재사용성 향상 (0) | 2023.05.27 |
4. EventFlow 도입 (0) | 2023.05.26 |