DevOps/Optimization

렌더링과 로딩최적화로 퍼포먼스 점수 30% 개선

닝닝깅 2024. 5. 9. 10:31

📍 개선 전 퍼포먼스 점수

 

내 프로젝트 랜딩페이지의 초기 Lighthouse 점수는 73점이었다. 만족스럽지 못한 점수로 최적화를 진행하기로 했다.

 

📍 성능저하 원인 분석 

Lighthouse 퍼포먼스 지표에 대해 알아보았다.

TTI - 사용자가 처음으로 이벤트를 발생시킬 수 있기까지 걸리는 시간
FCP - 브라우저에 첫번째 컨텐츠가 로딩되는 시간
SI - 컨텐츠가 얼마나 빠르게 로딩 되는 지
LCP - 가장 큰 컨텐츠가 로딩되는 시간
TBT - 로딩 중 중간중간 Block이 발생한 시간

 

그리고 지표를 기반으로 점수를 분석해보았고, 크게 두 가지 원인으로 성능이 저하된 거라 판단하였다.

1) 가장 큰 컨텐츠인 배너 이미지의 로딩 시간이 길다

2) 렌더링 차단 요소가 차지하는 시간이 길다

 

배너이미지 로딩시간 단축과 렌더링 차단요소인 스크립트와 스타일 시트 제어에 집중하여 최적화를 진행해보았다.

 

 

📍 시도한 방법

1) 배너 이미지 preload

preload를 사용하면 리소스를 우선적으로 가져올 수 있기 때문에 로딩 시간을 줄일 수 있다.

배너이미지는 큰 리소스었기 때문에 preload를 사용해주었다.

<link
  rel="preload"
  href="./src/assets/banner1_wp.webp"
  as="image"
  type="image/webp"
/>

 

2) webp로 배너 이미지 포맷 변환

webp 이미지 포맷은 이미지 품질은 유지하면서 크기는 줄여준다. 크기가 작아지기 때문에 로딩 시간을 줄일 수 있다.

 

랜딩페이지에 보이는 상품 이미지는 webp 포맷의 썸네일용 이미지를 통해 최적화를 거친 상태였지만 정적 파일로 갖고있는 png로 로딩되고 있었기 때문에 새롭게 변환해 추가해주었다.

 

네트워크 탭으로 속도를 측정해본 결과 28ms -> 5ms로 줄어든 것을 확인할 수 있었다.

 

+) 최근 webp는 대부분의 브라우저에서 지원하긴 하지만, 혹시 지원하지 않는 브라우저가 있다면 picture태그를 사용하여 브라우저별 지원하는 이미지 포맷에 맞출 수 있다.

<picture>
  <source srcSet={banner1wp} type="image/webp" />
  <source srcSet={banner1} type="image/png" />
  <img src={banner1} alt="배너이미지"/>
</picture>;

 

3) 스크립트 실행 시기 제어

스크립트는 렌더링 차단 요소로 분류된다. 렌더링 중 스크립트를 마주하게 되면 해당 스크립트가 다운로드되고 실행될 때까지 렌더링 과정이 중단되기 때문이다.

 

이를 방지하기 위해 스크립트의 defer 속성을 사용할 수 있다.

defer 속성은 스크립트가 백그라운드에서 다운로드되고 렌더링이 끝난 후 실행될 수 있도록 지연시킨다.

 

나는 결제SDK를 사용하기 위한 스크립트를 필요로 했기 때문에 해당 스크립트에 defer 속성을 추가하여 지연 실행되도록 하였다.

<script defer src="https://cdn.iamport.kr/v1/iamport.js"></script>

 

4) 폰트 최적화 ( 폰트 preload )

스타일 시트도 렌더링 차단 요소로 분류된다. 브라우저는 정확한 스타일 계산을 위해 CSS 파싱이 끝난 후에 렌더링이 진행된다. 그래서 웹 폰트 로딩이 지연되면 렌더링도 지연되는 것이다.

 

이를 방지하기 위해 preload로 웹폰트를 비동기적으로 로드할 수 있다.

비동기 로드가 완료되면 onload 이벤트 리스너를 통해 rel 속성을 스타일시트로 변경하여 실제 스타일시트로 적용되도록 한다. 그리고 이벤트 리스너가 한번 실행된 뒤에는 메모리 누수  방지를 위해 명시적으로 제거한다.

 

<link
  href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@100..900&display=swap"
  rel="preload"
  as="style"
  onload="this.onload=null;this.rel='stylesheet'"
/>

 

 

 

📍 개선 후 퍼포먼스 점수

96점으로 30%정도 향상된 점수를 받았다. 이외에도 더 최적화할만한 요소가 있는 지 찾아봐야겠다 ~~~