6.1 useMemo 개요

useMemo는 컴포넌트의 성능 최적화를 위하여 사용되는 대표적인 훅입니다. useMemo에서 Memo는 memoization을 뜻하며 이어지는 챕터에서 메모이제이션과 useMemo를 사용하는 이유가 무엇인지 살펴보겠습니다.

6.1.1 메모이제이션(Memoization)이란?

메모이제이션 기법은 연산의 결괏값을 메모리에 저장해 두고 이전 렌더링에서 계산한 값과 현재 렌더링에서의 결과가 같은 경우, 중복 연산을 할 필요 없이 저장해 둔 값을 재사용 할 수 있으므로 성능을 최적화할 수 있습니다. 예를 들어 A라는 함수의 전체 실행시간이 10초라고 가정해본다면 A 함수가 실행될 때마다 10초라는 시간이 걸리게 됩니다. 그러나 메모이제이션을 통해 값을 저장하고 함수가 실행될 때 결괏값만 재사용한다면 그만큼 연산을 줄일 수 있으므로 프로그램의 실행 속도를 올릴 수 있게 됩니다.

6.1.2 함수형 컴포넌트

아래 예제에서 함수형 컴포넌트는 MyComponent를 말하며, MyComponent를 호출하는 것은 함수형 컴포넌트가 렌더링이 되는 것을 의미하며 함수가 호출될 때마다 함수 내부의 모든 변수를 초기화합니다.

function calc(a, b) {
  return a + b
}

// 함수형 컴포넌트
const MyComponent() {
  const result = calc(3,5)

  return <p>{result}</p>
}

기본적으로 컴포넌트는 state가 변경되거나, props가 변경되었을 때마다 리렌더링이 되는데, 리렌더링이 될 때마다 MyComponent를 호출하게 되고 변수 result는 초기화되므로 매번 calc 함수를 실행합니다. 위 예제와 같이 간단한 계산만 하고 끝내는 함수라면 상관없겠지만, 만약 calc 함수가 실행될 때마다 약 10초 가량의 연산을 한다고 가정해보면 어떨까요?

리렌더링이 세 번만 일어나도 30초 가량의 연산이 수행되므로 매우 비효율적입니다. 이러한 현상을 해결하기 위해 우리는 useMemo를 사용하여 부하가 걸리는 함수의 결괏값을 메모리에 저장한 뒤, 리렌더링이 될 때 그 결괏값만 가져와서 재사용해 줌으로써 성능을 최적화할 수 있습니다.

6.2 useMemo의 기본 구조