[웹 성능 최적화] 실습2: 통계 사이트 최적화

April·2023년 1월 14일
0

React🚀

목록 보기
38/43
post-thumbnail
post-custom-banner

목표

  • 렌더링 최적화
    • 애니메이션 최적화 (Reflow, Repaint)
  • 로딩 성능 최적화
    • 컴포넌트 Lazy Loading (Code Splitting)
    • 컴포넌트 Preloading
    • 이미지 Preloading

실습툴

  • 크롬 Network 탭
  • 크롬 Performance 탭
  • webpack-bundle-analyzer


성능 최적화

실습할 사이트의 크롭 dev tool을 열고 Performance 탭에서 애니메이션 성능 측정하기

Reflow와 Repaint

애니메이션이 버벅이는 현상? 쟁크 현상

필요한 Frame을 모두 보여주지 못하고 유실되어 버벅이는 현상이 발생

쟁크 현상이 발생하는 이유?

브라우저 렌더링은

  • HTML, CSS를 가공해서 DOMCSSOM를 만들고
  • DOMCSSOM을 조합해서 Render Tree를 만들고
  • 각 요소의 위치와 크기를 계산하는 Layout 과정을 거쳐
  • 색을 채워넣는 Paint 단계를 진행하게 되고
  • 이렇게 만들어진 각 레이어를 합성하는 Composite 단계를 진행해서 화면에 보여주게 된다

그리고 어떤 상황에 의해 이 화면에 변경점이 생기면 이 렌더링 과정을 다시 진행하게 되는데 이 과정에서 매끄럽게 보이려면 초당 60 Frame (60FPS)을 보여줘야 한다.

초당 60 Frame (60FPS)을 지원하려면 0.016초 마다 1 Frame을 만들어야 하는데 짧은 시간 안에 렌더링을 만들지 못하면 쟁크 현상이 일어나게 되는 것..



Performance

애니메이션 성능 체크를 위해 Performance 탭 > 옵션에서 CPU를 6x로 체크 후 측정해본다

애니메이션 분석

성능 체크, 브라우저 렌더링 과정

점선 시점에 화면을 보여줘야 하는데 그렇지 못하고 있어서 쟁크 현상이 발생하고 있다

이렇게 브라우저에게 부담을 많이 주는 과정(Layout 과정, Paint 단계)을 건너뛰고 진행해서 개선해 볼 수 있다

  • GPU 도움받기: transform, opacity (GPU가 관여할 수 있는 속성) 변경

코드 적용해보기

CSS/transform

  • 개선 전 코드

    • width에 값으로 애니메이션을 발생시키고 있다
  • 개선 후 코드

성능 재 측정

  • 애니메이션 수정 전, 후 비교

  • FPS를 나타내는 부분을 보면 개선 후 일정하게 보여주는 것을 확인할 수 있다
  • (1) 부분이 메인스레드의 영역인데 보라색은 애니메이션이 발생하는 구간, s노란색은 JS 구간이다. transform으로 애니메이션을 개선해서 GPU의 도움을 받아 비교해보니 개선된 것을 확인할 수 있다


컴포넌트 Lazy Loading (Code Splitting)

Nextjs Project는 @next/bundle-analyzer으로 분석할 수 있다

yarn add @next/bundle-analyzer
package.json빌드된 후

bundle 파일 분석 (bundle analyzer)

설치

# webpack을 별도 커스텀하지 않고 사용하기
npm i --save-dev cra-bundle-analyzer
yarn add -D cra-bundle-analyzer

npx cra-bundle-analyzer

분석

  • react-image-gallery 모듈이 사이즈가 큰 편은 아니지만 처음부터 로딩될 필요는 없다. 모달창이 팝업되었을 떄 필요하므로 Lazy Loading을 적용해서 코드 분할(Code Splitting)로 개선할 수 있어 보인다

코드 적용해보기

  • 개선 후 코드

개선 후 재 분석

코드가 분리된 것을 확인할 수 있다

처음보다는 개선되었겠지만, 모달에서는 오히려 성능 저해가 발생할 수 있다

이런 경우 Preloading을 통해 개선할 수 있다

그럼 언제 Preload 해야할까?

컴포넌트 Preload 타이밍은 두 시점으로 바라볼 수 있는데,

  1. 버튼 위에 마우스가 over 되었을 때
  2. 최초 페이지 로드가 되고 모든 컴포넌트의 마운트가 끝났을 때

이번 실습에서는 1번 시점에 Preload를 해보자!



컴포넌트 Preloading

코드 개선: 마우스가 over 되었을 때 Preloading

  • 마우스가 오버 되었을 때의 시점을 onMouseEnter로 처리하고
  • 처리할 함수를 만들었다 handleMouseEnter
    • 마우스가 오버되었을 때 import를 시킴

네트워크 탭에서 확인해보기

마우스 오버했을 때 파일리 로드되는 것을 확인할 수 있다

마우스 오버하고 클릭하는 순간 보통 0.2초 정도가 소요되는데
파일이 커서 0.2초 이상 소요되는 경우는 개선의 효과를 볼 수 없다.
이런 경우는 모든 컴포넌트가 완료된 후 미리 로드시키도록 개선해 볼 수 있다

다시 한번 코드 개선: 모든 컴포넌트의 마운트가 끝났을 때 Preloading

  • 다시 수정한 코드

네트워크 탭에서 수정된 내용 다시 확인

최초 로딩이 끝난 후 이어서 바로 로딩되는 것을 확인할 수 있다


코드 리펙토링

필요할 때 마다 import 시키기 보다 util 함수 만들어서 재사용하게 개선하기



이미지 Preloading

컴포넌트 Preloading으로 개선했음에도 모달창을 팝업시켜보면 이미지는 여전히 느리게 로딩된다
이번 실습에서는 모달창에서 바로 확인되는 이미지를 Preloading 시켜 개선해보자!


new Image() 활용하기

주의할 점은 코드가 실행되는 시점에 바로 이미지를 로딩시킨다
즉, 불러올 이미지가 캐싱이 되는지 확인할 것!

  • 처음 로딩시켰을 때: 네트워크 탭에서 확인

  • 새로고침 했을 때: 캐싱된 것을 확인할 수 있다
    업로드중..

주의할점!

모든 이미지를 Preloading 시킬 수 있지만 그럴 경우 오히려 성능 저하가 발생할 수 있으므로 필요한 이미지에 Preloading 시키도록 한다!



profile
🚀 내가 보려고 쓰는 기술블로그
post-custom-banner

0개의 댓글