⚠️ useMemo 의 사용에 주의하세요

셔노·2023년 4월 17일
0

🔹useMemo란?

useMemo컴포넌트 리렌더링 간에 계산 결과를 캐싱할 수 있는 Hook(훅)이다.

그래서 성능상의 이유로만 사용되며, useCallback, 디바운싱, 동시 렌더링 등과 같은 기술과 함께 사용해야 한다. 이 훅은 일부 상황에서는 굉장히 도움이 되지만, 대부분의 개발자가 적절하게 사용하지 못하고 있다.

메모이제이션(memoization)은 대가 없이 제공되지 않는다.

하지만 그들은 최적화가 되기를 바라며, 모든 변수를 useMemo로 감싼다. 이 방법은 그저 가독성이 떨어지고 메모리 사용량을 증가할 뿐이다.

메모이제이션, 개념만 보았을 때는 굉장히 효율적이고 사용하기만 하면 최적화가 이루어질 것 같은 느낌이 들기도 합니다. 하지만 명확한 목적없이 무작정 메모이제이션을 사용하는 것은 오히려 비효율적입니다.

새로운 값을 만드는 것어딘가에 이전의 값을 저장해두고 메모이제이션 함수를 호출하고 의존성을 비교해서 가져올지 말지 여부를 판단하는 것 중 어떤 것이 비용이 더 적게 들까?

위의 문장에 대한 정답은 상황에 따라 다릅니다.

만약 새로운 값을 만드는 과정이 복잡하다면 메모이제이션을 사용하는 것이 더 효율적일 수 있습니다. 하지만 새로운 값을 만드는 과정이 복잡하지 않다면 메모이제이션을 사용하는 것은 오히려 비용이 더 많이 들수도 있습니다. 컴퓨터 자원의 측면뿐만 아니라 메모이제이션을 쓰면서 코드의 복잡도가 올라간다는 개발적인 측면의 비용도 무시할 수 없습니다.

🔹useMemo의 작동 원리

const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);

useMemo는 두가지 인자를 받습니다.

  • 첫번째 인자는 콜백함수이며, 이 함수에서 리턴하는 값이 메모됩니다.
  • 두번째 인자는 의존성 배열입니다.

메모이제이션을 할 때 주의해야 할 점은 만약 새로운 값을 만들어서 사용해야 하는 상황임에도 불구하고 이전의 결과를 그대로 활용해버리면 버그가 발생할 수 있다는 점입니다.

위의 예시에서 a, b 라는 두가지 변수를 이용해서 메모이제이션 하기 위한 값을 계산하고 있습니다. 그런데 만약 a, b 라는 값이 변경되었는데 이전의 값을 그대로 활용해버리면 의도한 결과와 다른 결과가 나오게 될 것입니다.

이런 상황을 방지하기 위해서 useMemo에서는 의존성 배열을 인자로 받아, 의존성 배열에 있는 값 중 하나라도 이전 렌더링과 비교했을 때 변경되었다면 메모된 값을 활용하는 것이 아니라 새로운 값을 다시 계산합니다.

🔹그럼 언제 useMemo의 사용을 피해야 할까요?

  • 최적화하려는 계산의 비용이 크지 않은 경우
    - useMemo를 사용함으로 발생하는 오버헤드가 더 클 수도 있다.
  • 메모이제이션이 필요한지 확실하지 않은 경우
    - 일단 useMemo 없이 코드를 작성한 다음, 문제가 발생하면 점진적으로 최적화를 하는 것이 좋다.
  • 메모하고 있는 값이 컴포넌트로 전달되지 않은 경우
    - JSX에서만 사용되고 컴포넌트 트리에 더 깊이 전달되지 않으면, 대부분의 경우 최적하를 피할 수 있다.
  • 의존성 배열이 너무 자주 변경되는 경우
    - useMemo는 항상 재계산되어, 성능적인 이점을 보기 어렵다.
profile
초보개발자

0개의 댓글