[웹 성능 최적화] 실습4: 이미지 갤러리 서비스 최적화

April·2023년 1월 24일
0

React🚀

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

목표

  • 로딩 성능 최적화
    • 이미지 지연(lazy) 로딩
  • 렌더링 성능 최적화
    • Layout Shift 피하기
      • CLS 지표 개선: 밀리는 현상 개선
    • useSelector 렌더링 문제 해결
    • Redux Reselect를 통한 렌더링 최적화
    • 병목 함수에 memoization 적용
    • 병목 함수 로직 개선하기

실습툴

  • 크롬 Network 탭

  • 크롬 Performance 탭

  • Lighthouse

  • React Developer Tools (Profiler)

    • 리액트가 렌더링 될 때의 상태 확인 관리 가능
  • Redux DevTools



성능 최적화

Layout Shift 피하기

Layout Shift란?

🤔 Layout Shift

화면상에서 요소들이 어떤 요인에 의해서 사이즈가 바뀌거나 위치가 바뀌는 현상 (=위치나 사이즈를 다시 계산해야 한다는 것. 사용성 저하)

Layout Shift 원인?!

  • 사이즈가 정해져 있지 않은 이미지
  • 사이즈가 정해져 있지 않은 광고
  • 동적으로 삽입된 컨텐츠
  • Web font(FOIT, FOUT)

Lighthouse에서 Layout Shift 확인해보기

  • 0~1 사이의 수치를 가지는데, 1은 모든 것이 변했다 라는 의미..

  • 이미지의 사이즈가 정해지지 않은 것도 확인이 된다
    • 💡이미지 요소에 명시적인 너비 및 높이를 설정하면 레이아웃 변경 횟수를 줄이고 누적 레이아웃 변경을 개선할 수 있다 (=Layout Shift 개선!)


코드 개선하기

정적 사이즈를 적용하게 되면 반응형에서는 개선하기 어렵기 때문에 이미지의 사이즈를 비율에 맞게 변경하기

  • 변경 전

  • 변경 후

    • 이미지가 로딩되기 전 이미지가 위치해야 할 자리만큼 패딩이 자리하기 코드를 개선하고
    • 이미지가 로딩되면 패딩의 위치 위에 올리게끔 코드 개선



이미지 지연(lazy) 로딩

react-lazyload 라이브러리

스크롤이벤트로 동작하는 라이브러리

npm install --save react-lazyload

코드 개선하기



useSelector 렌더링 문제 해결

components 탭으로 렌더링 시점 체크해보기

React Developer Tools > components 탭

어떤 타이밍에 어떤 컴포넌트가 렌더링 되는지 확인 가능

  • components 탭으로 렌더링 시점 체크하기 위해서는 render함수가 실행되는 시점에 Highlight하기 체크 설정을 해야한다

  • 메뉴를 클릭하는 시점에 렌더링되는 부분이 Highlight된다


불필요한 재렌더링 원인 파악하기

  • 자세히 살펴보면 모달창을 띄웠을 때 의도하지 않게 모달 뒤의 이미지들도 재렌더링 되고 있는 것이 확인된다 😰
  • 이렇게 불필요한 렌더링이 발생하는 이유는
    • 이미지들과 모달이 redux로 연결되어 있고
    • redux의 상태가 바뀌면서 구독하고 있는 이미지와 모달이 변경되기 때문..

useSelector 문제 해결 방법

  • Object를 새로 만들지 않도록 State 쪼개기
  • 새로운 Equality Function 사용
    • 기본적으로 useSelector는 단순 비교를 한다
    • object 형태로도 비교가 가능하게끔 두 번쨰 인자로 Equality Function 사용할 수 있다

코드 개선하기

Object를 새로 만들지 않도록 State 쪼개기

  • 변경 전: Object로 비교하고 있음..

  • 변경 후: 값(string, boolean)을 하나하나 비교

새로운 Equality Function 사용

  • 변경 후: react-redux에서 제공하는 shallowEqual 함수를 두 번째 인자로 추가

그외

  • useSelector 내부에서 filter 함수를 처리하지 말고! 밖으로 빼서 처리해야 불필요한 렌더링을 방지할 수 있다


Redux Reselect를 통한 렌더링 최적화

개선점 파악

  • category는 렌더링에 불필요한 값. 꼭 useSelector로 가져와야 하나?
  • category, allPhotos, loading 외의 값이 추가되어 추가된 값으로 렌더링이 필요할 경우, photos를 계산하는 값이 필요하지 않는 상황임에도 photos는 연산하게 되는 문제점 발생

Redux Reselect 라이브러리로 문제점 개선하기

Reselect는 memoization 기법을 사용해서 함수에 똑같은 인자가 들어오면 결과값을 미리 캐싱된 값으로 반환해주는 라이브러리

설치

npm install reselect
yarn add reselect

사용법

const selectFilteredPhotos = createSelector(
  [가져올 값들], 
  (가져온 값들) => {
    로직
  }
);

코드 개선하기


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

0개의 댓글