[Next.js] 이미지 사이즈 최적화로 성능 개선하기
📌 현재 상황
지금 개발중인 Next SNS프로젝트에서는 이미지가 메인 화면에 처음 진입 시 바로 노출된다. 때문에 이러한 부분이 LCP에 영향을 줄 수 있을 것 같았다. LCP는 Last Contentful Paint로 가장 마지막 텍스트 또는 이미지가 표기되기까지 소요되는 시간이기 때문이다. LCP를 조금이라도 줄여 Lighthouse 성능을 개선해보고자 우선 이미지 사이즈 최적화를 하게 되었다.
📌 문제 상황 분석하기
그렇다면 기존에 LCP는 얼마였을까? 아래 이미지를 보면 알 수 있듯이 4.1초로 성능이 좋지 않았다.
추측해봤을 때, 사용자가 추가한 이미지를 Storage에 원본 그대로 저장하다보니 LCP에 영향을 미칠 것 같았다. Next에서 제공하는 Image 컴포넌트는 렌더링 시 이미 이미지를 압축하여 주긴 한다. 하지만, 여러 이미지를 로드해야하는 SNS 서비스 특성상 여러 이미지를 로드하다보면 사이즈가 성능에 영향을 미칠 수 있다. next에서 이미지 처리하는 과정을 줄여준다면 성능이 개선될 수 있다고 한다.
📌 이미지 사이즈 최적화 해보자
아래에는 최적화 이전에 업로드 했던 이미지이다. 아래 이미지의 원래 크기는 100.73kb이다. 아래 네트워크 탭에 보면 next image 컴포넌트를 활용했기 때문에 49.4kb로 압축된 걸 볼 수 있다. 거의 절반을 압축하는 걸 볼 수 있다.
그럼 내가 직접 최적화를 해보려고 한다. 나는 browser-image-compression 요 라이브러리를 사용해줬다.
npm i browser-image-compression
1️⃣ 1차 시도 : 600 * 600, 0.6 압축퀄리티
압축 결과 : 80% 이상 압축
(기존 100.73kb 이미지 압축 -> 55.88kb -> Next 압축 15.5kb)
하지만 압축을 높게 할수록 화질이 안좋아진다... 무조건적인 압축이 아닌 사이즈를 조정해서 적절한 압축 범위를 설정해야 한다. 기존에는 이미지 노출 사이즈인 너비 600px에 맞게 설정해두었는데, 픽셀과 화질 둘다 떨어져버린 것이다. 이미지 해상도는 너비와 높이를 줄이면 픽셀수가 줄어들어서 해상도가 떨어진 것으로 추측이 된다. 그래서 코드를 아래처럼 2배 정도 기준으로 수정해서 압축했다.
2️⃣ 2차 시도 : 1000 * 1000, 0.8 퀄리티
// 변경 전
const MAX_WIDTH = 600;
const MAX_HEIGHT = 600;
const MAX_SIZE_MB = 1;
const WEBP_QUALITY = 0.6;
// 변경 후
const MAX_WIDTH = 1000;
const MAX_HEIGHT = 1000;
const MAX_SIZE_MB = 1;
const WEBP_QUALITY = 0.85;
const compressedFile: File = await imageCompression(file, {
maxSizeMB: MAX_SIZE_MB,
maxWidthOrHeight: Math.max(MAX_WIDTH, MAX_HEIGHT),
useWebWorker: true,
initialQuality: WEBP_QUALITY,
fileType: 'image/webp',
});
결과적으로 기존 (49.4kb -> 33.3kb) 정도로 압축되었다.
📌 다시 Lighthouse 성능을 측정해보면?
🎉 최종적으로 LCP 는 4.1에서 3.7초로 0.4초가 줄었다. 물론 큰 개선은 아닐수도 있지만 이렇게 하나하나 개선해나가다보면 언젠간 사용성이 정말 좋아질수도 있지 않을까
📌 느낀점
이미지 사이즈 최적화를 해보면서 서비스 성능을 개선하는 것의 중요성을 깨달았고 그 과정이 꽤난 재미있다는 것을 알게 되었다. 앞으로 더 다양한 방법을 웹사이트를 최적화해보려고 한다.
직접 해보고 부딪혀보면서 많이 경험해보는 게 좋은 것 같다!