라이브러리 중에 잘 사용하지 않지만 사이즈가 큰 것에 집중을 했다. 그리고 사이즈가 작은 것으로 대체할만한 것이 있으면 교체하는 방향으로 계획을 세웠다.
로딩 및 캐릭터의 애니메이션을 보여주는 애니메이션 라이브러리 lottie가 있다. 자주 사용하지 않는데 0.5mb 비중을 차지하고 있어 꼭 필요한 시점에만 불러올 수 있도록 수정했다.
before
dynamic imports
const Lottie = dynamic(()=>import('react-lottie'), {ssr:false})
after
그 결과 LoadingComponent하나만 보더라도 97.49KB > 9.17KB로 축소된 것을 알 수 있다. 페이지 렌더링 시에 즉각 사용하지 않는 컴포넌트들은 다 이처럼 레이지 로딩을 적용해 나가려고 한다.
추가로... 용량이 적은 라이브러리로의 교체의 예시
1. moment > day.js : day로 변경하거나 간단한 것은 순수 date 객체를 적용한다.
2. loadash : 가능하면 직접 구현, loadash-es로 사용하는 함수만 import해오도록 변경 중
profiler로 성능 측정 시 처음 불러오는데 걸린 시간이다.
근소하지만 bundle 사이즈를 관리해 로딩 및 스크립트 시간을 줄이는데 도움을 줄 수 있다.
link 태그의 구글폰트를 통해 폰트를 사용했는데, network payload가 커서 속도를 지연한다고 한다. 파일 크기가 작은 woff 로컬에 직접 폰트를 저장했다.
profiler를 돌린 결과이다. 무려 26.8초나...
홈화면에서 굉장히 많은 이미지들을 로딩하는데 갯수도 갯수지만 이미지 사이즈가 매우 큰 것, 또 http1 서버를 통해 이미지를 내려받아 최적화가 진행되지 못했다.
Next.js로 개발했는데 Next Image가 적용되어있지 않았다. 그 이유는 img태그를 사용할때 쉽게 이미지를 조절할 수 있었던 것에 비해 NextImage는 width, height를 지정해주어야 하는 등 까다로운 부분이 있었기 때문인 것 같다.
넥스트 이미지는 이미지의 형식을 WebP로 변경해주는데, 이런 차세대 형식 이미지 AVIF and WebP는 기존 JPEG 및 PNG에 비해 압축 및 품질 특성이 우수하다. 중요 js 리소스가 로드된 후에 이미지를 지연 로드 시켜 (Defer offscreen images) TTI를 줄여준다.
*TTI(Time To Interactive): 사용자 입력에 신속하게 안정적으로 응답할 수 있는 시점까지의 시간
next/image 태그를 사용하면 next 내부에 캐시된 파일을 확인할 수 있다.
네트워크 탭에서도 이미지를 불러오는 네트워크 정보에 X-Nextjs-Cache
항목을 확인할 수 있는데 캐시된 이미지를 불러와 HIT으로 나타남을 알 수 있다.
적용 결과로 이미지 한장당 사이즈를 (1.3MB > 55KB) 로 축소시킬 수 있었다.
next/image로 이미지를 최적화했음에도 체감되는 로딩속도가 빠르지 않다면?
나의 경우에는 더 빠르게 로딩할 수 있는 방법이 있을까 알아보다가 알게된 라이브러리이다. 넥스트에서는 기본적으로 sqoosh라는 라이브러리를 통해 이미지 최적화를 돕고있는데 production 환경에서는 sharp를 적용해야 한다는 것. 이게 적용되어있지 않으면 빌드타임에러로 sharp-missing-in-production
이라는 에러를 준다.
(*참고 문서 : https://nextjs.org/docs/messages/sharp-missing-in-production)
나도 적용해 보려고 부단히 노력했으나 잘되지 않았다.
알고보니 vercel로 배포하면 자동으로 sharp가 적용되어있다는 것 !
그래서 에러문구가 뜨지 않았던 거구나..?!
더 빠르게 로딩할 수 있는 방법은 놓쳤지만 놓친 것이 아니었다 ㅎㅎㅎ
무튼 vercel에서 배포하지 않았다면 sharp를 설치해볼 것!
서버 이미지가 http1으로 내려오고 있었는데 http2로 개선했다.
위 결과,
페이지에 접속할 때 체감될 정도로 빠르게 로딩되었다. lightHouse 지표로는 Time to interactive가 18.8초에서 6.2초로 개선되었다.