# [[React 성능 최적화 (React Performance Optimization)]]

## 📌 Brief Summary
React 성능 최적화는 불필요한 연산과 재렌더링을 최소화하고 브라우저의 중요 렌더링 경로(Critical Rendering Path)를 효율적으로 관리하여 애플리케이션의 속도 및 응답성을 극대화하는 과정이다 [1, 2]. 이는 렌더링 계단식(Re-render Cascade) 문제 해결, 초기 번들 크기 감소, 리플로우(Reflow) 및 리페인트(Repaint) 제어를 주요 목표로 삼는다 [3-6]. 최근에는 React 18의 자동 배칭(Automatic Batching)과 React 19 컴파일러의 자동 메모이제이션 도입으로 인해, 개발자의 수동 최적화 부담이 크게 줄어들고 프레임워크 및 빌드 타임 레벨에서 성능 향상이 이루어지는 추세이다 [7-9].

## 📖 Core Content

*   **불필요한 재렌더링 방지 및 가상 DOM 최적화**
    부모 컴포넌트의 상태가 변경될 때 모든 자식 컴포넌트가 재렌더링되는 '렌더링 계단식' 문제는 성능 저하의 주된 원인이다 [3, 10]. 이를 방지하기 위해 기존에는 `React.memo`, `useMemo`, `useCallback`과 같은 수동 메모이제이션 기법을 사용하여 참조(Reference)의 동등성을 유지하고 불필요한 비교(Diffing) 연산을 차단했다 [11-13]. 또한, React 18에 도입된 자동 배칭(Automatic Batching)은 이벤트 핸들러뿐만 아니라 Promise나 `setTimeout` 같은 비동기 작업 내의 여러 상태 업데이트를 단일 렌더링으로 묶어주어 가상 DOM 작업과 렌더링 횟수를 획기적으로 줄여준다 [7, 14, 15].

*   **빌드 타임 최적화: React 컴파일러(React Compiler)**
    React 19 컴파일러는 애플리케이션 코드를 구문 분석(AST)하여 정적 값과 반응형 값을 자동으로 식별하고, 최적의 위치에 메모이제이션 경계를 삽입하는 빌드 타임 도구이다 [8, 9, 16, 17]. 이를 통해 개발자가 수동으로 의존성 배열을 관리하며 겪는 과도한 메모이제이션(Over-memoization)이나 누락 문제를 해결하고, 값이 변경된 특정 부분만 렌더링하는 세밀한 반응성(Fine-Grained Reactivity)을 달성하여 성능 최적화 작업의 90%를 제거한다 [18-20].

*   **동시성 렌더링과 파이버(Fiber) 아키텍처**
    React 16부터 도입된 파이버 아키텍처는 동기적으로 블로킹되던 기존 렌더링 방식을 벗어나, 렌더링 작업을 작은 단위로 나누고(Time-slicing) 우선순위(Lane model)를 부여하여 중단 및 재개가 가능하도록 만들었다 [21-24]. 이를 기반으로 하는 `useTransition` 및 `useDeferredValue` 훅을 사용하면, 무거운 데이터 필터링이나 화면 전환 같은 비긴급 업데이트의 우선순위를 낮춤으로써 타이핑과 같은 긴급한 상호작용이 지연 없이 처리되도록 하여 UI의 응답성(INP 개선)을 높일 수 있다 [25-28].

*   **브라우저 렌더링 최적화: Reflow와 Repaint 최소화**
    React가 가상 DOM을 업데이트한 후, 브라우저가 화면을 그리는 과정에서 레이아웃 계산(Reflow)과 시각적 업데이트(Repaint)는 큰 비용을 수반한다 [5, 6, 29]. 렌더링 성능을 개선하려면 React Fragment를 사용해 불필요한 DOM 노드 래퍼를 줄이고 DOM의 깊이를 얕게 유지해야 한다 [30, 31]. 100개가 넘어가는 긴 리스트의 경우 화면에 보이는 노드만 렌더링하는 가상화(Virtualization) 라이브러리를 도입하여 다중 노드 생성 비용을 극적으로 줄일 수 있다 [32, 33]. 더불어 애니메이션 구현 시 레이아웃을 다시 계산하는 속성 대신 `transform` 속성 등을 활용해 GPU 가속을 적용하면 리플로우를 피할 수 있다 [34-36].

*   **번들 사이즈 제어 및 렌더링 전략 고도화**
    초기 로딩 속도(LCP)를 개선하려면 다운로드해야 할 JavaScript 번들 크기를 최소화해야 한다. `React.lazy()`를 활용한 라우트 레벨의 코드 스플리팅을 적용하면 초기 번들 크기를 30~50%가량 줄일 수 있다 [37]. 한 걸음 더 나아가 서버에서만 실행되는 React Server Components(RSC)를 활용하면 무거운 라이브러리나 정적 데이터 페칭 로직이 브라우저로 전송되지 않아 JavaScript 번들 크기를 '0 바이트'에 가깝게 줄이고 수화(Hydration) 비용을 완전히 제거할 수 있다 [38-40].

## 🔗 Knowledge Connections
- **Related Topics:** [[Virtual DOM (가상 DOM)]], [[Critical Rendering Path (중요 렌더링 경로)]], [[React Compiler (React 컴파일러)]], [[React Server Components (RSC)]], [[Concurrent Rendering (동시성 렌더링)]]
- **Projects/Contexts:** [[코어 웹 바이탈(Core Web Vitals) 개선 프로젝트]], [[프론트엔드 컴포넌트 기반 아키텍처(CBA) 구축]]
- **Contradictions/Notes:** React 18의 자동 배칭(Automatic Batching) 기능은 기본적으로 활성화되어 렌더링 최적화에 기여하지만, 사용자가 즉각적인 시각적 피드백(예: 입력 포커스, 폼 값 즉각 업데이트)을 필요로 하는 경우에는 `flushSync` API를 사용하여 의도적으로 배칭을 우회하고 동기적 렌더링을 강제해야 한다 [28, 41, 42]. 한편 기존 React 생태계에서는 `useMemo`와 같은 수동 최적화가 필수적이었으나, React 컴파일러 도입 이후에는 이들이 불필요해지며 의도적인 제어나 서드파티 라이브러리 대응과 같은 예외적 상황에서만 사용하는(Escape Hatch) 방식으로 패러다임이 바뀌고 있다 [19, 43-45].

---
*Last updated: 2026-04-25*