[번역] React의 성능을 최적화하는 10가지 방법

Hyun Jin·2023년 8월 18일
0

리액트 최적화 방법

핵심 : "Component가 렌더링 되는 것을 최소한으로 하라!"


1. useMemo()


  • React에서 CPU 소모가 심한 함수들을 캐싱하기 위해 사용되는 React Hook 중 하나.
  • useMemo 의 구조 :
    useMemo(()=> func, [input_dependency])
    func은 캐시하고 싶은 함수이고, input_dependency는 useMemo가 캐시할 func에 대한 입력의 배열로서 해당 값들이 변경되면 func이 호출된다.

2. 가상화된 List


만약 거대한 list data를 렌더링 한다면 브라우저의 viewport에 보여지는 부분만 렌더링하고 나머지는 스크롤 할때 보여지도록 하는 것을 권장한다. 이것은 "windowing" 이라 부르며, 많은 React 라이브러리들이 존재한다. 이 중 Brian Vaughn이 개발한 react-window(뷰포트 바깥에서 로딩/감추기 가능)와 react-virtualized가 있다.

3. React.PureComponent

React.PureComponent는 기본 component 바탕에서 state와 prop값을 체크하여 component가 업데이트 되어야 하는지 확인한다.

⇒ 최신 리액트에서는 memo 를 사용해서 함수형으로 변환하는 것을 권장한다.(공식문서)

Note
Unlike PureComponent, [memo](https://react.dev/reference/react/memo) does not compare the new and the old state. In function components, calling the [set function](https://react.dev/reference/react/useState#setstate) with the same state already prevents re-renders by default, even without memo.

4. Caching functions ⇒ useCallback()

5. Reselect selectors 사용하기


reselect를 사용하면 Redux 상태 관리가 최적화 된다. 리덕스 이뷰터블하게 동작한다는 것은 action이 dispatch 할때마다 새로운 객체 참조가 생성 된다는 뜻이다. 이것은 컴포넌트에서는 변경 되지 않았지만 오브젝트 참조가 변경될 경우 리렌더링이 되므로 성능에 방해가 되는 요소가 될 수도 있다.

Reselect 라이브러리는 Redux state를 캡슐화하여 component를 확인하고 렌더링 할지 안할지 여부를 알려준다.

따라서 reselect는 메모리 참조가 서로 다르지만 변경되었는지 확인하기 위해 이전 및 현재 Redux 상태를 얕게 체크함으로써 시간을 절약하게 한다. 필드가 변경된 경우 React에게 리렌더링 해야 한다고 알려주고 필드가 변경되지 않을 경우 새로운 상태 객체가 생성되었음에도 불구하고 리렌더를 취소한다.

Reselect 라이브러리를 기반으로 하는 createSelector 를 사용해서 새로운 값을 반환하면 연산을 새로 수행하는 대신 이전에 캐싱해 두었던 값을 반환하게 된다.

6. Web worker API


Web worker : UI 흐름을 방해하지 않고 메인 스레드와 동시에 실행할 수 있는 게이트웨이.

자바스크립트 코드는 싱글 스레드에서 동작한다. 동일한 스레드에서 오래걸리는 프로세스를 실행하면 UI 렌더링 코드에도 심각한 영향을 미치므로 최선의 방책은 프로세스를 다른 스레드로 옮기는 것이다.

  • 참고사이트 : [MDN] Web Workers API, [MDN] Worker
    • **Web Worker를 사용한 이미지 로딩** 브라우저에서는 자바스크립트로 작성된 어플리케이션의 멀티스레딩을 위해 웹 워커 API를 제공한다. 웹 워커에서 실행되는 스크립트는 메인 스레드에서 분리되어 독립된 스레드에서 실행되므로 앱이 실행되는 머신의 CPU, 메모리 리소스를 더 효율적으로 활용할 수 있다.
      • 웹워커 사용법 : 링크 참고

      • 웹 워커를 사용했을 때의 장점 :
        - 화면 업데이트를 최소화하여 성능을 향상시킨다.
        - 이미지 로딩 작업이 다른 DOM의 업데이트와 UI 상호작용에 미치는 영향을 최소화한다.
        - Image 객체를 생성하지 않고도 이미지 로딩 상태, 성공, 실패 여부를 UI에 동적으로 업데이트할 수 있다.

        웹 워커를 사용하지 않아도 웹 개발과 성능에 큰 문제가 없는 경우가 대부분이다. 하지만 메인 스레드에서 많은 메모리를 사용하고 있고 성능에 영향을 미치는 것 같다면 백그라운드로 진행해도 되는 작업을 웹 워커에서 처리하는 방법을 고려해볼 수 있다.

7. Lazy Loading


Lazy loading은 부하를 단축하기 위해 자주 사용되는 최적화 기법 중 하나이다. Lazy Loading은 일부 웹 앱 성능 문제의 위험을 최소화 하는데 도움이 된다.

React에서 component를 lazy load를 이용하기 위해 React.lazy() API를 사용한다.

React.lazy는 React v16.6에 새로 추가된 기능이다. 이것은 React Component를 쉽고 직관적으로 lazy-loading과 코드 스플리팅을 사용하기 위해 제안된 방법이다.

8. React.memo()

9. useCallback()

10. shouldComponentUpdate() ⇒ useEffect() 로 대체

profile
새싹 프론트엔드 개발자

1개의 댓글

comment-user-thumbnail
2023년 8월 18일

좋은 글이네요. 공유해주셔서 감사합니다.

답글 달기