Files
2nd/10_Wiki/Topics_Dev/“React가 빠른 이유” 및 렌더링 최적화 개념.md
T

30 lines
6.0 KiB
Markdown

# [[“React가 빠른 이유” 및 렌더링 최적화 개념|“React가 빠른 이유” 및 렌더링 최적화 개념]]
## 📌 Brief Summary
React가 빠른 핵심 이유는 브라우저의 무거운 실제 DOM 조작을 최소화하기 위해 가벼운 메모리 내 표현인 [[Virtual DOM|Virtual DOM]]을 사용하고, 효율적인 Reconciliation(조정) 알고리즘을 통해 변경된 부분만 갱신하기 때문입니다 [1-4]. 렌더링 최적화의 근본적인 목표는 연산 비용이 높은 브라우저의 Reflow(레이아웃)와 Repaint를 줄이는 것이며 [5-7], 최근 React는 Fiber 아키텍처, 자동 배칭(Automatic Batching), [[React Compiler|React Compiler]] 등을 도입하여 개발자의 수동 개입 없이도 동시성 렌더링과 메모이제이션을 자동화해 UI 성능을 극대화하고 있습니다 [8-11].
## 📖 Core Content
**브라우저 렌더링 과정 ([[Critical Rendering Path|Critical Rendering Path]]) 및 병목**
브라우저는 HTML을 파싱하여 [[DOM (Document Object Model)|DOM(Document Object Model]]을 구축하고, CSS를 파싱하여 CSSOM을 만든 뒤 이 둘을 결합하여 화면에 보일 요소들만 포함하는 렌더 트리([[Render Tree|Render Tree]])를 생성합니다 [12-15]. 이 트리를 바탕으로 각 요소의 정확한 크기와 위치를 계산하는 Layout(또는 Reflow) 단계를 거쳐, 최종적으로 화면에 픽셀을 그리는 Paint(또는 Repaint) 작업을 수행합니다 [5, 16-20]. 요소의 너비, 높이, 위치 등을 변경하면 전체 페이지의 레이아웃을 다시 계산해야 하는 Reflow가 발생하며, 이는 매우 연산 비용이 높고 렌더링 성능 저하의 주된 원인이 됩니다 [5, 6, 21, 22].
**Virtual DOM과 Reconciliation (조정 알고리즘)**
직접적인 DOM 조작의 비효율성을 극복하기 위해 React는 Virtual DOM(VDOM)이라는 가상의 UI 트리를 메모리에 유지합니다 [1, 2, 4]. 상태가 변경되면 React는 새로운 Virtual DOM을 생성하고 이전 트리와 비교(Diffing)합니다 [2, 23]. React의 조정 알고리즘은 O(n)의 시간 복잡도를 가지며, "서로 다른 타입의 요소는 다른 트리를 생성한다"는 가정과 리스트 렌더링 시 `key` 속성을 사용하여 변경, 추가, 삭제된 최소한의 노드만 식별해 실제 DOM에 패치(Patch)합니다 [1, 3, 24-26]. 이를 통해 불필요한 Reflow와 Repaint를 방지합니다.
**Fiber 아키텍처와 우선순위 기반 스케줄링**
React 16부터 도입된 Fiber 아키텍처는 동기식 렌더링의 한계를 해결하기 위해 렌더링 작업을 'Fiber 노드'라는 작은 작업 단위로 나눕니다 [8, 27-30]. 이 구조는 '타임 슬라이싱([[Time-Slicing|Time-Slicing]])'을 가능하게 하여, 렌더링 도중에도 사용자 입력이나 애니메이션 같은 긴급한 작업(Sync Lane)이 발생하면 기존 작업을 중단(Pause) 및 양보(Yield)하고 우선순위가 높은 작업을 먼저 처리할 수 있도록 돕습니다 [27, 30-34]. 그 결과 메인 스레드 차단을 막아 끊김 없는 UI(동시성 렌더링)를 제공합니다.
**React 최신 버전의 자동 렌더링 최적화**
* **자동 배칭 (Automatic [[Batching|Batching]]):** [[React 18|React 18]]은 이벤트 핸들러뿐만 아니라 Promise, setTimeout 등 모든 출처에서 발생하는 상태 업데이트를 묶어서 단 한 번의 리렌더링으로 처리합니다 [9, 35-38]. 이로 인해 Virtual DOM 디핑 연산과 실제 DOM 업데이트 횟수가 크게 줄어듭니다.
* **React Compiler:** [[React 19|React 19]]에서 도입된 컴파일러는 빌드 타임에 코드의 AST(추상 구문 트리)를 분석하여 정적 값과 반응형 값을 식별하고 자동으로 메모이제이션을 삽입합니다 [10, 39-41]. 이는 상위 컴포넌트의 상태 변경으로 인한 하위 컴포넌트의 연쇄 리렌더링(Re-render Cascade)을 차단하며, 개발자가 직접 `useMemo``useCallback`을 작성하는 수고를 덜어줍니다 [10, 11, 42-44].
**서버 컴포넌트 ([[React Server Components|React Server Components]], RSC)**
기존 CSR(클라이언트 사이드 렌더링)이나 SSR(서버 사이드 렌더링) 환경에서는 클라이언트가 결국 방대한 크기의 [[JavaScript|JavaScript]] 번들을 다운로드하고 실행(Hydration)해야 하는 부담이 있었습니다 [45-48]. React [[Server Components|Server Components]]는 서버에서 컴포넌트를 실행한 뒤 직렬화된 UI와 HTML만을 클라이언트로 스트리밍합니다 [49-51]. 결과적으로 서버 컴포넌트는 클라이언트 측 자바스크립트 번들에 0바이트를 추가하며, 브라우저의 다운로드 및 실행 부담을 없애 무거운 데이터 연산이나 정적 UI 렌더링 속도를 극대화합니다 [49, 51-53].
## 🔗 Knowledge Connections
- **Related Topics:** `[[Virtual DOM|Virtual DOM]]`, `Reconciliation`, `Critical Rendering Path`, `[[React Fiber|React Fiber]]`, `Hydration`, `[[Reflow and Repaint|Reflow and Repaint]]`
- **Projects/Contexts:** `React 18 Automatic Batching`, `[[React 19 Compiler|React 19 Compiler]]`, `React Server Components`, `[[Next.js|Next.js]] Rendering Strategies`
- **Contradictions/Notes:** 이전까지는 불필요한 렌더링을 막기 위해 개발자가 `useMemo`, `useCallback`, `React.memo`를 사용한 수동 메모이제이션을 구현하는 것이 필수적인 최적화 기법이었습니다 [43, 54, 55]. 그러나 React 19 컴파일러의 등장으로 이러한 수동 메모이제이션의 90% 이상이 불필요해졌으며, 컴파일러가 최적의 메모이제이션 경계를 자동으로 판단하여 적용합니다 [10, 44, 56, 57]. 단, 타사 라이브러리(Third-party library)가 렌더링마다 불안정한 참조를 반환하는 경우 컴파일러 최적화가 실패할 수 있어, 여전히 제한적인 상황에서는 수동 제어가 필요할 수 있습니다 [58, 59].
---
*Last updated: 2026-04-25*