[React] 메모이제이션(Memoization) 활용하기

해피몬·2024년 7월 27일
post-thumbnail

메모이제이션이란? 🤔

메모이제이션(Memoization)은 이전에 계산한 값을 메모리에 저장해두고, 동일한 연산이 필요할 때 저장된 값을 재사용하는 기술임. React에서 메모이제이션을 사용하면 불필요한 연산과 렌더링을 줄여 성능을 최적화할 수 있음. 특히 복잡한 계산이나 데이터 변동이 적은 컴포넌트에 효과적임.

React에서 메모이제이션이 필요한 이유 🌟

React 애플리케이션에서는 상태가 변경되거나 props가 업데이트될 때마다 컴포넌트가 재렌더링됨. 이 과정에서 이전과 동일한 값이나 함수가 재계산되거나 재생성될 수 있으며, 이는 성능 저하를 초래할 수 있음. 메모이제이션을 활용하면 변경이 없는 경우 이전 값을 재사용해 불필요한 연산을 줄이고 성능을 최적화할 수 있음.

React의 메모이제이션 도구 🔧

React.memo: 컴포넌트 메모이제이션

React.memo는 컴포넌트를 메모이제이션하는 고차 컴포넌트(Higher-Order Component)로, props가 변경되지 않으면 이전에 렌더링된 결과를 재사용함.

import React from 'react';

const ChildComponent = React.memo(({ value }) => {
  console.log("Child component rendered");
  return <div>Value: {value}</div>;
});

function ParentComponent() {
  const [count, setCount] = React.useState(0);

  return (
    <>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <ChildComponent value={count} />
    </>
  );
}

useMemo: 값 메모이제이션

useMemo는 복잡한 계산을 메모이제이션하여, 의존성 값이 변경되지 않는 한 캐시된 값을 반환함. 주로 무거운 연산이나 반복적인 데이터 필터링이 필요한 경우 사용함.

import React, { useState, useMemo } from 'react';

function ExpensiveCalculationComponent({ number }) {
  const expensiveCalculation = useMemo(() => {
    console.log("Calculating...");
    return number ** 2;
  }, [number]);

  return <div>Result: {expensiveCalculation}</div>;
}

function App() {
  const [count, setCount] = useState(0);
  const [number, setNumber] = useState(5);

  return (
    <>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <ExpensiveCalculationComponent number={number} />
    </>
  );
}

useCallback: 함수 메모이제이션

useCallback은 함수를 메모이제이션하여, 의존성이 변경되지 않으면 동일한 함수 인스턴스를 반환함. 자식 컴포넌트에 함수를 props로 전달할 때 유용함.

import React, { useState, useCallback } from 'react';

const ChildComponent = React.memo(({ onClick }) => {
  console.log("Child component rendered");
  return <button onClick={onClick}>Click me</button>;
});

function ParentComponent() {
  const [count, setCount] = useState(0);

  const handleClick = useCallback(() => {
    console.log("Button clicked");
  }, []);

  return (
    <>
      <button onClick={() => setCount(count + 1)}>Increment Count</button>
      <ChildComponent onClick={handleClick} />
    </>
  );
}

언제 메모이제이션을 사용해야 할까? 🔍

메모이제이션을 무조건 사용하는 것이 좋은 것은 아님. 메모이제이션이 오히려 메모리 사용량을 늘리고 성능에 영향을 미칠 수 있기 때문임. 다음과 같은 경우에 메모이제이션을 고려하는 것이 좋음.

  • 복잡한 계산이 있는 경우: 반복적으로 무거운 계산을 수행해야 할 때 useMemo를 사용하여 이전 계산 결과를 재사용할 수 있음.
  • 불필요한 컴포넌트 재렌더링이 발생할 때: React.memo와 useCallback을 사용하여 자식 컴포넌트가 불필요하게 렌더링되지 않도록 최적화할 수 있음.
  • 함수를 props로 전달해야 할 때: 함수가 props로 전달되며 동일한 함수 인스턴스를 유지해야 할 때 useCallback을 사용하여 재생성을 방지할 수 있음.

메모이제이션을 과도하게 사용하지 말아야 할 이유 🚫

메모이제이션은 성능을 최적화하는 데 유용하지만, 잘못 사용하면 오히려 성능에 부정적인 영향을 줄 수 있음.

  • 메모리 사용 증가: 메모이제이션을 사용하면 메모리에 저장된 데이터가 계속 유지되므로, 메모리 사용량이 증가할 수 있음.
  • 불필요한 오버헤드: 단순한 연산이나 상태 업데이트에서는 메모이제이션의 장점이 크지 않아 오히려 오버헤드가 발생할 수 있음.
  • 의존성 관리의 어려움: 메모이제이션의 의존성 배열을 잘못 설정하면, 의도치 않게 이전 값이 반환되어 문제가 발생할 수 있음.
profile
슬기로운개발생활🤖

0개의 댓글