React.js 메모이제이션(Memoization)으로 렌더링 성능 최적화

작성일 :

React.js 메모이제이션(Memoization)으로 렌더링 성능 최적화

React는 컴포넌트 기반의 라이브러리로, 상태 변화에 따라 효율적으로 UI를 업데이트합니다. 하지만 때로는 불필요한 재렌더링이 발생하여 성능 저하를 초래할 수 있습니다. 이러한 문제를 해결하기 위해 메모이제이션(memoization)을 활용할 수 있습니다. 메모이제이션을 사용하면 불필요한 계산이나 렌더링을 피하고 애플리케이션의 성능을 최적화할 수 있습니다. 이 글에서는 React.memo, useMemo, 그리고 useCallback을 사용하여 성능을 개선하는 방법을 알아보겠습니다.

React.memo

React.memo는 고차 컴포넌트(Higher Order Component)로, 컴포넌트가 동일한 props로 여러 번 렌더링되는 것을 방지합니다. 이를 통해 불필요한 렌더링을 피할 수 있습니다. 예를 들어, 다음과 같은 간단한 컴포넌트를 살펴봅시다:

jsx
import React from 'react';

const MyComponent = (props) => {
  console.log('컴포넌트 렌더링');
  return <div>{props.value}</div>;
};

export default MyComponent;

위의 컴포넌트는 props.value가 변경될 때마다 다시 렌더링됩니다. 이를 React.memo로 감싸서 최적화할 수 있습니다:

jsx
import React from 'react';

const MyComponent = React.memo((props) => {
  console.log('컴포넌트 렌더링');
  return <div>{props.value}</div>;
});

export default MyComponent;

이제 props.value가 변경되지 않는 한, 컴포넌트는 다시 렌더링되지 않습니다. React.memoprops 검사에 매우 효과적입니다. 하지만 객체나 배열 같은 참조형 데이터를 사용할 때는 별도로 이를 관리해야 합니다.

useMemo

useMemo 훅은 계산 비용이 큰 함수의 결과를 메모이제이션하는 데 사용됩니다. 이는 불필요한 연산을 피하고 계산된 값을 재사용함으로써 성능을 최적화합니다. 다음은 useMemo의 사용 예시입니다:

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

const MyComponent = ({ items }) => {
  const expensiveCalculation = (items) => {
    console.log('비싼 계산 수행 중');
    return items.reduce((acc, item) => acc + item.value, 0);
  };

  const totalValue = useMemo(() => expensiveCalculation(items), [items]);

  return <div>총합: {totalValue}</div>;
};

export default MyComponent;

위 코드에서는 items 배열이 변경될 때만 expensiveCalculation 함수가 호출됩니다. 이를 통해 불필요한 재계산을 피할 수 있습니다.

useCallback

useCallback 훅은 메모이제이션된 콜백 함수를 반환하여 컴포넌트가 다시 렌더링될 때마다 동일한 콜백 함수가 생성되는 것을 막습니다. 이는 특히 props로 콜백 함수를 전달하는 경우 유용합니다. 다음은 useCallback의 사용 예시입니다:

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

const MyComponent = () => {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => {
    setCount(count + 1);
  }, [count]);

  return <button onClick={increment}>증가</button>;
};

export default MyComponent;

위 코드에서 increment 함수는 count 값이 변경될 때만 새로 생성됩니다. 이를 통해 콜백 함수가 빈번하게 변경되는 문제를 해결할 수 있습니다.

성능 최적화 시 주의사항

메모이제이션은 성능 최적화에 매우 효과적이지만, 무조건 사용해서는 안 됩니다. 메모이제이션 자체도 일정한 비용이 들기 때문에, 계산 비용이 크지 않으면 오히려 역효과가 날 수 있습니다. 비용이 큰 연산이나, 빈번한 렌더링을 방지할 필요가 있는 경우에만 사용하는 것이 좋습니다.

또한, React.memo, useMemo, useCallback은 모두 동일한 입력에 대해 동일한 출력을 보장해야 합니다. 이 규칙을 지키지 않으면 예기치 않은 버그가 발생할 수 있습니다.

결론

메모이제이션은 React 애플리케이션의 성능을 최적화하는 데 강력한 도구입니다. React.memo, useMemo, useCallback을 적절히 사용하면 불필요한 렌더링과 계산을 줄이고, 애플리케이션의 반응성을 크게 개선할 수 있습니다. 하지만 이는 적절한 상황에서만 사용해야 하며, 무조건 남용해서는 안 됩니다. 항상 코드의 성능과 복잡도 사이에서 균형을 맞추는 것이 중요합니다.