반응형
리액트 성능 최적화의 꽃이자, 동시에 가장 오용되기 쉬운 기능이 바로 **메모이제이션(Memoization)**입니다. "일단 다 감싸고 보자"는 식의 접근은 오히려 애플리케이션의 성능을 떨어뜨릴 수 있습니다.
이번 섹션에서는 메모이제이션의 정확한 동작 원리와 언제 사용하고, 언제 멈춰야 하는지에 대한 명확한 기준을 세워보겠습니다.
1. 왜 메모이제이션이 필요한가? (참조 동일성)
리액트에서 컴포넌트는 자신의 state가 바뀌거나, 부모 컴포넌트가 재렌더링될 때 함께 재렌더링됩니다. 이때 자바스크립트의 참조 동일성(Referential Equality) 문제가 발생합니다.
- 문제: 컴포넌트가 재렌더링될 때마다 내부에서 선언된 객체, 배열, 함수는 새로운 메모리 주소를 가집니다.
- 결과: 리액트 입장에서는 내용은 같아도 "새로운 값"이 들어온 것으로 간주하여 자식 컴포넌트까지 불필요하게 다시 그리게 됩니다.
2. 메모이제이션의 3총사
2-1. React.memo: 컴포넌트 자체를 기억하기
부모 컴포넌트가 바뀌어도 전달받는 props가 변하지 않았다면 재렌더링을 건너뛰게 합니다.
- 사용 시점: 컴포넌트가 같은 props로 자주 렌더링되거나, 렌더링 비용이 큰 UI일 때.
- 주의: Props로 객체나 함수를 넘길 경우, 뒤에 나올 useMemo나 useCallback 없이 React.memo만 쓰면 효과가 없습니다. (참조값이 매번 바뀌기 때문)
2-2. useMemo: 값(Value)을 기억하기
비싼 계산(예: 대용량 데이터 필터링, 정렬)의 결과값을 메모리에 저장합니다.
JavaScript
const sortedList = useMemo(() => {
return heavySort(data); // 데이터가 바뀔 때만 실행됨
}, [data]);
2-3. useCallback: 함수(Function)를 기억하기
함수 인스턴스 자체를 기억합니다. 주로 React.memo를 사용 중인 자식 컴포넌트에 함수를 props로 전달할 때 필수적으로 사용됩니다.
[Image showing the relationship between useCallback in parent and React.memo in child]
3. ⚠️ 메모이제이션의 "암(Dark Side)": 무분별한 사용의 위험성
많은 개발자가 놓치는 사실은 **"메모이제이션도 비용이다"**라는 점입니다.
- 메모리 비용: 이전 값을 메모리에 들고 있어야 하므로 메모리 점유율이 높아집니다.
- 비교 비용: 재렌더링 시마다 의존성 배열(dependency array) 내의 값들을 하나하나 비교하는 오버헤드가 발생합니다.
- 가독성 저해: 코드가 장황해지고 유지보수가 어려워집니다.
현명한 판단 기준:
- 단순히 텍스트를 출력하는 작은 컴포넌트에는 React.memo를 쓰지 마세요.
- 간단한 계산(예: a + b)에는 useMemo를 쓰지 마세요.
- 먼저 코드를 최적화하고, 그래도 성능 문제가 있을 때 측정(Profiling) 후 적용하세요.
4. 실전 최적화 전략 (Best Practice)
| 상황 | 추천 전략 |
| 단순 UI 컴포넌트 | 최적화 불필요 |
| 차트, 리스트 등 무거운 컴포넌트 | React.memo 적용 |
| 부모에서 자식으로 함수 전달 시 | useCallback + 자식 React.memo 조합 |
| 복잡한 데이터 가공 로직 | useMemo 적용 |
반응형
'개발 > React' 카테고리의 다른 글
| [고급반] Step 2-1. 확장성 있는 디자인 패턴: Compound Components (0) | 2025.12.23 |
|---|---|
| [고급반] Step 1-3. 대용량 데이터 렌더링: Windowing 기법으로 1만 개 리스트 다루기 (0) | 2025.12.23 |
| [고급반] Step 1-1. 재조정(Reconciliation)과 가상 DOM의 내부 원리 (0) | 2025.12.23 |
| [중급반] Step 3-3. 비동기 통신 및 에러 처리 고급 기법 (0) | 2025.12.15 |
| [중급반] Step 3-2. GraphQL 연동 심화 (REST API의 대안) (0) | 2025.12.15 |