성능지표 개선을 통한 최적화

junamee·2023년 2월 27일
2

프론트엔드

목록 보기
13/16
post-thumbnail

bundleAnalyzer분석

라이브러리 중에 잘 사용하지 않지만 사이즈가 큰 것에 집중을 했다. 그리고 사이즈가 작은 것으로 대체할만한 것이 있으면 교체하는 방향으로 계획을 세웠다.

로딩 및 캐릭터의 애니메이션을 보여주는 애니메이션 라이브러리 lottie가 있다. 자주 사용하지 않는데 0.5mb 비중을 차지하고 있어 꼭 필요한 시점에만 불러올 수 있도록 수정했다.

before

  • dynamic imports

    • 빌드 시점 용량을 차지 하지 않는다.
    • Lottie 라이브러리 dynamic import
const Lottie = dynamic(()=>import('react-lottie'), {ssr:false})
  • 사용하지 않는 import 와 선언 삭제
    • Lottie 라이브러리를 사용하는 AnimationBox 컴포넌트에서 애니메이션 파일을 prop으로 전해주는데 기본값이 설정되어있었다.
    • 그렇지만 위에서 말했든 자주 쓰이지 않는 만큼 기본값도 선언될 필요가 없어 보이며 심지어 쓰고있지 않았던....😱 바로 삭제!

after

그 결과 LoadingComponent하나만 보더라도 97.49KB > 9.17KB로 축소된 것을 알 수 있다. 페이지 렌더링 시에 즉각 사용하지 않는 컴포넌트들은 다 이처럼 레이지 로딩을 적용해 나가려고 한다.

추가로... 용량이 적은 라이브러리로의 교체의 예시
1. moment > day.js : day로 변경하거나 간단한 것은 순수 date 객체를 적용한다.
2. loadash : 가능하면 직접 구현, loadash-es로 사용하는 함수만 import해오도록 변경 중

profiler로 성능 측정 시 처음 불러오는데 걸린 시간이다.
근소하지만 bundle 사이즈를 관리해 로딩 및 스크립트 시간을 줄이는데 도움을 줄 수 있다.


라이트하우스 분석

1. font개선

link 태그의 구글폰트를 통해 폰트를 사용했는데, network payload가 커서 속도를 지연한다고 한다. 파일 크기가 작은 woff 로컬에 직접 폰트를 저장했다.

2. Image 개선

profiler를 돌린 결과이다. 무려 26.8초나...
홈화면에서 굉장히 많은 이미지들을 로딩하는데 갯수도 갯수지만 이미지 사이즈가 매우 큰 것, 또 http1 서버를 통해 이미지를 내려받아 최적화가 진행되지 못했다.

use Next image

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) 로 축소시킬 수 있었다.

sharp 적용하기

next/image로 이미지를 최적화했음에도 체감되는 로딩속도가 빠르지 않다면?
나의 경우에는 더 빠르게 로딩할 수 있는 방법이 있을까 알아보다가 알게된 라이브러리이다. 넥스트에서는 기본적으로 sqoosh라는 라이브러리를 통해 이미지 최적화를 돕고있는데 production 환경에서는 sharp를 적용해야 한다는 것. 이게 적용되어있지 않으면 빌드타임에러로 sharp-missing-in-production 이라는 에러를 준다.
(*참고 문서 : https://nextjs.org/docs/messages/sharp-missing-in-production)

나도 적용해 보려고 부단히 노력했으나 잘되지 않았다.
알고보니 vercel로 배포하면 자동으로 sharp가 적용되어있다는 것 !
그래서 에러문구가 뜨지 않았던 거구나..?!
더 빠르게 로딩할 수 있는 방법은 놓쳤지만 놓친 것이 아니었다 ㅎㅎㅎ
무튼 vercel에서 배포하지 않았다면 sharp를 설치해볼 것!

use HTTP2

서버 이미지가 http1으로 내려오고 있었는데 http2로 개선했다.

  • 하나의 네트워크 연결
    http2는 http1보다 많은 이점을 제공하는데, 다중화(multiflexing)를 지원해서 http1이 한번에 하나의 요청을 처리할 수 있는 것에 반해, 한 번에 여러가지의 이미지를 동시에 요청할 수 있다.
  • HTTP2의 요청단위, 프레임
    이진 데이터로된 작은 조각으로 데이터를 분할하여 전송하기 때문에 대량의 데이터를 전송할때 속도를 더 높일 수 있다.
  • 헤더 압축
    헤더의 크기를 압축해 대역폭이 줄어들고 더 빠르게 전송할 수 있다. (대역폭이 제한적인 모바일 네트워크에서 효과적)

위 결과,
페이지에 접속할 때 체감될 정도로 빠르게 로딩되었다. lightHouse 지표로는 Time to interactive가 18.8초에서 6.2초로 개선되었다.

profile
아티클리스트 - bit.ly/3wjIlZJ

0개의 댓글