Preparing workspace
← 목록으로

[Tech Article] 리액트 최적화 요약집 (useCallback, useMemo ...)

Tech Article

2021.05.04

리액트 최적화 요약집 (useCallback, useMemo ...)



1. 리액트 최적화란 무슨 뜻일까?

  • 최적화란 프로그램 변현 기술로 코드를 이용하여 CPU, 메모리의 리소스가 적게 소모시키며 속도도 향상해주도록 하는 것
  • 리액트 최적화는 리액트 기술을 활용하여 관련 코드를 이용한 성능 개선을 시켜준다고 볼 수 있다.

2. 데이터를 업데이트 하는 과정에서 불변성을 지켜야 되는데 그 이유는?

  • 자식 컴포넌트에 부모 컴포넌트에서 해당 데이터가 생기거나 할 경우 자식 컴포넌트까지 렌더링이 된다
  • 이런 상황은 Virtual DOM에만 리렌더링을 해주어 큰 문제가 일어나지 않는다.
    하지만 최악의 조건인 상황이나 관련 데이터들이 한 번에 수백 개씩 혹은 그 이상이라면 성능 손실이 발생하며
    이는 렌더링에서 수행하는 로직이 많을수록, 많은 컴포넌트를 출력할수록 손실을 커질 것임.

3. 리액트에서는 렌더링이 되는 대표적인 조건

1. state 변경이 있을 때
2. 부모 컴포넌트가 렌더링 될 때
3. 새로운 props이 들어올 때
4. shouldComponentUpdate에서 true가 반환될 때
5. forceUpdate가 실행될 때
  • 여기서 1번과 2번은 얕은 비교를 통해 새로운 값인지 여부를 따져 리렌더링을 한다
  • 클래스 컴포넌트에서는 렌더링이 될 경우, render 메서드만 리 렌더링이 되지만,
    함수형 컴포넌트(hooks)에서는 위 조건 중에 하나라도 될 경우 함수 전체가 재실행

4. 위 문제를 해결할 수 있는 useMemouseCallback

  • useMemo
  • 복잡한 함수 결괏값을 기억 (함수의 리턴값을 기억)
  • useRef는 일반 값을 기억
  • 사용하는 이유
    useCallback 사용만으로는 하위 컴포넌트의 리렌더를 막을 수 없음
    하위 컴포넌트가 참조 동일성에, 의존적인, 최적화된 Purecomponent 이어야만
    비로소 불필요한 리 렌더링을 막을 모든 것이 완성됨.
  • 사용법
  • 고차 컴포넌트이므로 사용 중인 component를 memo로 감싸주기만 하면 됨.
  • props에 대해 기본으로 제공되는 얕은 비교가 아닌 커스텀을 하고 싶다면
    두 번째 인자로 비교 함수를 넣어 사용할 수 있음

useMemo는 메모리제이션된 을 반환한다 (리액트 공식 문서)

  • useCallback
  • 함수 자체를 기억하고 있음
  • 의존성에 포함된 값이 변경되지 않는다면 이전에 생성한 함수 참조 값을 반환해줌
  • 사용하는 이유
    현재 하위 컴포넌트에 전달하는 콜백 함수를 inline 함수로 사용하고 있다거나,
    컴포넌트 내에서 함수를 생성하고 있다면 (프로그래밍 구동에는 문제가 없겠지만)
    새로운 함수 참조 값을 계속해서 만들고 있는 것!!!
  • 사용법
  • 인라인 콜백과 그것의 의존성 값의 배열을 전달
    useCallback은 콜백의 메모이제이션된 버전을 반환할 것임.
    그 메모이제이션된 버전은 콜백의 의존성이 변경되었을 때에만 변경됨.
  • 자식컴포넌트에 함수를 넘길 때 무조건 useCallback를 적용시켜줘야 한다.
    자식 입장에서는 부모가 매번 새로운 함수를 주는 것이라고 판단한다 고 한다.
  • useCallback의 동작방식
useEffect에서 제2의 인자로 의존성 배열 안에 값이 존재할 경우
  => componentDidUpdate
useEffect에서 제2의 인자로 의존성 배열로 빈 배열로 존재할 경우
  => componentDidMount
  • useEffect와 동작방식이 유사함!

useCallback는 메모리제이션된 함수를 반환한다 (리액트 공식 문서)

  • 주의해야할 점
    • 함수 생성자체가 비용이 클 경우, 클릭 이벤트처럼 여러 번 누를 경우에
      기억을 잘해서 처음 찍혔단 값을 계속 가지고 있는다.
      그래서 두번째 인자에 배열 안으로 같이 넣어줘야. (useEffect와 유사 방식)
    • useMemo, useCallback, useEffect가 2번째 인자가 중요하다
      (어느 시점에 실행이 될지 정해주기 때문!)

느낀점

  • 항상 함수형 컴포넌트(hooks)만 쓰니
    class형 컴포넌트의 componentDidMountcomponentDidUpdate를 볼때마다
    무슨 의미를 뜻하는 지 몰랐는데 이 정리 잘되어 있는 블로그를 보면서 많은 정리를 할 수 있었던 것 같다!
    그리고 존재만 알았던 useMemouseCallback의 특징도 알 수 있었던 글이라 좋았다!

참고 링크

Ranohub

0%