캡스톤 프로젝트 "Nado" 리팩토링 (3) : useCallback() , useMemo() 등의 React hook으로 성능 개선 (2)

MinKyu Tae·2023년 1월 18일
0

Nado 프로젝트

목록 보기
5/6

🎉 리팩토링

동기

React 프로젝트를 여러번 하면서 useCallback() , useMemo() 등의 성능 최적화를 위한 hook을 사용해 본 경험이 없었다.
이번 프로젝트에서 한 번 제대로 사용해보자 결심했지만 시간에 쫓겨 도입하지 못했던 것이 불편했다. 이번 기회에 성능 최적화를 연습할 겸 제대로 리팩토링을 하고자 한다.

📌 리팩토링 목표

목표 목록

  • 기존 네비게이션 로직 개선.
  • Router 부분 코드 개선.
  • useCallback() , useMemo() 등의 React hook으로 성능 개선.
  • 웹 뷰에서 CSS 충돌 문제 해결.

🎈 useCallback() , useMemo() 등의 React hook으로 성능 개선.

문제 상황

이전과 동일하게 성능 최적화를 고려하지 않은 설계로 불필요한 리렌더링이 되는 컴포넌트들이 존재한다.
프로젝트 전반에 걸쳐서 성능 최적화가 필요한 상황이다.

🧨 기존 주문 홈 페이지 렌더링

해당 페이지에서는 총 3번의 렌더링이 발생한다.
1. Initial render.
2. useEffect()에 작성된 dispatch(가게 목록 요청) 함수에 의해 redux의 가게 목록이 업데이트 되었고 이 가게 목록을 구독하는 useSelector()에 의해 render.
3. React.StrictMode에 의해 render. (개발 모드에서 확인)

위의 이미지를 보면 3번의 렌더링 시, 모든 컴포넌트들이 리렌더링이 된 것을 확인할 수 있다.

✨ 개선 방법

기존 개선 방법

  1. React.memo()를 사용하여 하위 컴포넌트들이 리렌더링 되지 않도록 한다.
  2. useCallback()을 사용하여 리렌더링이 발생하더라도 함수를 새로 만들지 않도록 한다.
  3. 함수형 업데이트를 사용하도록 setState 로직을 개선하여 useCallback의 의존성 배열을 줄인다.

개선 중 발생한 문제

문제가 된 가게 목록 컴포넌트 (OrderStoreList.jsx)

가게 홈 페이지 컴포넌트로부터 props로 storeList(가게 목록)을 전달 받는 하위 OrderStoreList(가게 목록 컴포넌트)가 매번 리렌더링이 발생했다.

이에 대한 원인은 React.memo()가 이전 props들과 값을 비교할 때, 이전에 저장하고 있던 storeList와 새로 리렌더링 되면서 업데이트 된 storeList 객체가 같지 않다고 판단했기 때문이었다.

해결 방법

React.memo()의 두 번째 인자로 이전에 저장하고 있던 storeList와 새로 전달받은 storeList를 비교하는 isSame() 콜백 함수를 구현하여 전달했다.

React.meme()에 isSame()을 추가한 후의 코드

🎨 개선 후 주문 홈 페이지 렌더링 상황

비용 비교

개선 전

개선 후

React.memo()useCallback()을 이용하여 이 페이지에서 사용하는 모든 하위 컴포넌트들을 재상용 할 수 있었고 리렌더링 비용을 크게 줄일 수 있었다.

📃 후기

이 리팩토링 기록 외에도 프로젝트 전체에 걸쳐서 최적화를 위한 리팩토링을 진행했다. 이번 리팩토링을 통해 그동안 능숙하다고 생각했던 React에 대해 공부가 부족했다는 것을 느꼈다. 하지만 useCallback()과 같은 hook들과 useSelector()를 이용한 성능 최적화 방법을 연습해 볼 수 있었으며 개발 중 아쉬웠던 부분을 다소 해결했기에 만족스럽다.

다음 프로젝트부터는 이번에 공부한 성능 최적화 방식을 적극적으로 도입할 수 있을 것 같다.

profile
꾸준히 성장하는 웹개발자 태민규입니다.

0개의 댓글