안녕하세요 메이토입니다 🍅
프론트엔드라면 렌더링에 대한 최적화를 신경쓰지 않을 수 없겠죠?
그럴때마다 나오는 개념, Memoization 에 대해 알아보고, 그렇다면 "모든 곳에 Memoization 해야 하나?" 라는 의문점을 풀어보려고 합니다.
Memoization (메모이제이션)
복잡한 함수 호출의 결과값을 함수에 저장해놓고, 같은 입력이 반복될 때 저장한 값을 반환하도록 하여 속도를 높임
즉, 동일한 계산을 반복해야 할 때 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산을 하지 않도록 하는 것이고, 이것이 곧 React에서는 컴포넌트의 잦은 리렌더를 방지하기 위한 최적화 방법일 것 같습니다.
1. useCallback
- 함수를 메모이 제이션
const memoizedCallback = useCallback(() => {
doSomething(a, b);
}, [a, b]);
React 컴포넌트 안에서 정의한 함수는,
컴포넌트가 렌더링될 때마다 새로운 함수 객체로 만들어집니다.
이렇게 생성된 함수가 하위 컴포넌트로 전달될 경우,
매 렌더마다 props가 바뀌었다고 판단되어 불필요한 리렌더링이 발생할 수 있어요.
useCallback을 사용하면,
의존성 배열(a, b)이 바뀌지 않는 이상 기존 함수를 재사용하게 되어
불필요한 함수 재생성을 막을 수 있습니다.
2. useMemo
- 값을 메모이 제이션
const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]);
비용이 많이 드는 연산(예: 복잡한 정렬, 필터링 등)을 반복 수행하지 않도록 결과값을 캐싱해두고 재사용할 수 있게 도와주는 훅입니다.
의존성 배열의 값이 변경되기 전까지는, 이전에 계산한 memoizedValue를 반환합니다.
3. React.memo
- 컴포넌트를 메모이 제이션
const MemoizedComponent = React.memo(MyComponent);
React.memo는 고차 컴포넌트(HOC)로, 컴포넌트의 props가 변경되지 않으면 리렌더링을 생략합니다.
리렌더링 비용이 큰 컴포넌트이거나, props가 자주 바뀌지 않는 경우 매우 유용하게 사용될 수 있어요.
필요하다면 React.memo(Component, areEqual) 형태로
커스텀 비교 함수를 넣어 props 비교 방식을 세밀하게 제어할 수도 있습니다.
❗️무조건 Memoization이 좋나요?
결론부터 말하면, 그렇지 않습니다.
🧱 오히려 비용이 더 들 수도 있다!
useMemo, useCallback, React.memo는 메모이제이션을 위한 부가적인 연산과 메모리 사용이 필요합니다.
복잡한 로직이 아니라면 메모이제이션하는 오버헤드가 더 커서 오히려 성능이 나빠질 수 있습니다.
🔍 의존성 배열 관리가 까다롭다!
의존성 배열([])을 잘못 작성하면…
- 의존성이 변경되어도 값이 갱신되지 않아 버그가 생기거나
- 매번 리렌더되어 최적화가 무의미해질 수 있습니다.
상황추천 Memoization 도구
| 복잡한 계산이 반복될 때 | useMemo |
| props로 함수를 전달할 때 | useCallback |
| 리렌더링 비용이 큰 컴포넌트 | React.memo |
'리액트 톺아보기' 카테고리의 다른 글
| [React] 제어 컴포넌트 vs. 비제어 컴포넌트 (0) | 2025.05.08 |
|---|---|
| [Hook] useImperativeHandle (0) | 2025.05.01 |
| [React] React의 렌더링 트리🌳 (0) | 2025.04.24 |