안녕하세요! 열일하는 프론트엔드 개발자 제이입니다. 올해 봄, 신입으로 입사한 지 얼마 안되어 서비스 소개 페이지를 개발한 적이 있는데요, 리팩토링을 위해 다시 돌아왔습니다.
캐시를 끄고, 네트워크 쓰로틀링을 3g환경으로 제한하여 소개 페이지의 성능을 확인해봤습니다. 히어로 이미지의 로드가 상당히 느린 것을 확인할 수 있었습니다.
Lighthouse 검사 결과를 보면 LCP지표가 매우 안 좋다는 것을 알 수 있었습니다. LCP는 페이지가 로드될 때 화면 내에 있는 가장 큰 이미지나 텍스트 요소가 렌더링되기까지 걸리는 시간을 나타내는 지표입니다. 페이지에 진입하여 히어로 이미지가 뜨기까지 11.3초가 걸렸음을 알 수 있습니다.
10MB라니😞 원본 이미지를 그대로 사용한 문제를 확인했습니다. 본인이 낳은 문제는 스스로 해결을 해야겠죠. Lighthouse는 이미지 최적화를 위해 다음과 같이 제안합니다.
- 차세대 형식을 사용해 이미지 제공하기
- WebP 및 AVIF와 같은 이미지 형식은 PNG나 JPEG보다 압축률이 높기 때문에 다운로드가 빠르고 데이터 소비량도 적습니다.
- 이미지 크기 적절하게 설정하기
- 적절한 크기의 이미지를 게재하여 모바일 데이터를 절약하고 로드 시간을 단축하세요.
먼저 반응형 웹으로 개발되었기 때문에 모바일에서는 크기를 줄인 이미지를 제공하는 방법을 고려할 수 있습니다. 하지만 저는 일반적인 디바이스뿐만 아니라 레티나 이상의 고성능 디스플레이에서도 이미지의 퀄리티를 유지하고 싶었습니다.
레이아웃 최상단, 주요 부분을 차지하는 히어로 이미지의 품질 저하가 사용자 경험과 서비스 인식에 부정적인 영향을 미칠 수도 있을 것 같다고 생각했기 때문입니다.
고로 이미지 사이즈 조절은 먼저 이미지 압축을 시도한 후에 고민해보도록 하고, 저희는 IE를 지원하지 않는 정책이기에 webP 이미지 형식으로 변환하려 합니다. caniuse.com에 따르면 webP의 브라우저 호환율은 매우 높은 편입니다.
squoosh는 구글에서 제공하는 이미지 압축 서비스입니다. webP로 변환했을 뿐인데 98%의 용량이 압축된 고화질, 저용량의 이미지가 되었습니다.
189kB 용량이라면 모바일 대응을 따로 하지 않아도 될 것 같다고 판단하였습니다.
저희 서비스는 Next.js로 개발되었고, 자동으로 이미지를 최적화해주는 Image컴포넌트를 적극적으로 활용하고 있습니다.
<Image
tw="object-cover w-full h-full"
priority
alt=""
placeholder="blur"
src={히어로이미지}
/>
그리고 사실 Next.js의 Image컴포넌트는 자체 loader로 squoosh를 사용해 이미지를 최적화합니다.
다만 사용자 최초 요청 시에 Next.js 서버에서 최적화된 이미지를 제공하기 위한 이미지 프로세서 로직을 수행하고 이후에 캐시 된 이미지를 제공하기 때문에 미리 최적화 작업을 하였습니다.
next 프로젝트를 build하면 다음과 같은 경고문이 나옵니다.
요약하면 next는 production 환경에서 이미지 로더로 최적화 성능이 더 좋은 sharp를 추천합니다. 사용법도 간단합니다.
yarn add sharp
sharp를 설치하면 next/image는 sharp module을 불러와 loader로 sharp를 사용합니다.
똑같이 노캐쉬 3g 환경에서 테스트한 결과 높은 성능 최적화가 이루어졌음을 확인할 수 있었습니다.
[참고]
https://nextjs.org/docs/messages/sharp-missing-in-production
https://fe-developers.kakaoent.com/2022/220714-next-image/
https://oliveyoung.tech/blog/2023-06-09/nextjs-image-optimization/