[리액트 딥 다이브] 02-5-컴포넌트와-함수의-무거운-연산을-기억해-두는-메모이제이션

  1. 리액트에서 제공하는 API 중 useMemo, useCallback 훅과 고차 컴포넌트인 memo를 사용해 리엑트에서의 렌더링을 최소한으로 줄일 수 있다.
  2. 이러한 렌더링 최적화 기법을 메모이제이션 기법이라고 한다.

→ 렌더링 비용과 메모이제이션 비용 중 어떤 게 더 비싼가라는 질문이 등장

일부 컴포넌트에서는 메모이제이션을 하는 것이 성능에 도움이 된다. 우리는 두 가지 선택권이 있다.

  1. memo를 컴포넌트의 사용에 따라 잘 살펴보고 일부에만 적용하는 방법
  2. memo를 일단 다 적용하는 방법

1️⃣ 섣부른 최적화는 독이다. 필요한 곳에서만 메모이제이션 하자.

  1. 이상적인 상황이다.
  2. 메모이제이션 역시 어디까지나 비용이 발생하는 작업이다. 따라서 최적화가 필요한 곳에서만 사용해야 한다.
    1. 값을 비교하고 렌더링 또는 재계산이 필요한지 확인하는 비용
    2. 이전 결과물을 저장해 두었다가 다시 꺼내와야 하는 비용
  3. 가벼운 작업 자체는 캐싱하는 것 보다 매번 이 작업을 수행해 결과를 반환하는 것이 더 빠를 수 있다.
  4. 이러한 비교와 렌더링이 문제가 되었다면, 리액트에서는 진작에 모든 컴포넌트를 PureComponent 혹은 memo로 감싸두었을 것이다.
  5. 이를 개발자에게 선택권으로 줬다는 것은 메모이제이션이 은탄환이 아니라는 사실을 방증한다.

2️⃣ 모조리 메모이제이션 해 버리자.

  1. 컴포넌트의 복잡성이 증가하는 상황에서 이 기조를 유지할 수 있을까?
  2. 많은 개발자들은 생각보다 최적화나 성능 향상에 쏟을 시간이 많지 않다는 것.
  3. 잘못된 memo로 지불되는 비용 : props에 대한 얕은 비교가 발생하면서 지불해야 하는 비용.
  4. 기본적으로 리액트의 재조정 알고리즘 덕분에 결과물은 어떻게든 저장하고 있다. 따라서 우리가 지불해야 하는 비용은 props에 대한 얕은 비교 뿐인 것이다.
  5. 반면 memo를 하지 않았을 때 발생하는 문제는 다음과 같다.
    1. 렌더링을 함으로써 발생하는 비용
    2. 컴포넌트 내부 복잡한 로직의 반복 실행
    3. 위의 두 경우가 자식 컴포넌트 까지 실행된다.
    4. 기존 트리와 새로운 트리의 비교 비용

3️⃣ 리딥다 저자의 사견

  1. 리액트를 배우고 있는 단계이거나, 깊게 이해하고 싶고, 그럴 시간적 여유가 있다면 섣부른 최적화를 하지 않고, 어느 지점에서 성능상 이점을 누릴 수 있는지 살펴보는 식으로 적용해야 한다.
  2. 현업에서 리액트를 사용하고 있거나, 시간적 여유가 없다면 일단 의심스러운 곳에 모두 적용할 것을 권장한다.