---
id: wiki-2026-0508-virtual-dom과-reconciliation
title: Virtual DOM과 Reconciliation
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [VDOM, React Fiber, Virtual DOM]
duplicate_of: none
source_trust_level: A
confidence_score: 0.93
verification_status: applied
tags: [react, frontend, rendering, vdom, fiber, signals]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
  language: typescript
  framework: React-19
---

# Virtual DOM과 Reconciliation

## 매 한 줄
> **"매 UI 의 in-memory tree (VDOM) 의 매 diff → 매 minimal real-DOM mutation 만 commit."** React 가 2013년 도입 → 2017년 Fiber rewrite → 2024년 React 19 (compiler) 로 evolve. 매 2026 은 매 fine-grained reactivity (SolidJS, Svelte 5 runes) 와 매 architectural rivalry — 매 VDOM 의 default 지위 의 erosion.

## 매 핵심

### 매 VDOM 작동
1. **Render**: JSX → VDOM tree (object literal).
2. **Diff (reconcile)**: prev tree vs next tree 의 비교 — 매 O(n) heuristic.
3. **Commit**: minimal real-DOM operation 의 batch apply.

### 매 React Fiber (2017+)
- **Unit of work**: 매 fiber node — 매 component 의 단위.
- **Interruptible**: 매 work loop 가 매 yield 가능 — 매 priority-based scheduling.
- **Double buffering**: current tree + work-in-progress tree.
- **Lanes (2020)**: priority bitmask — sync, transition, idle.

### 매 Reconciliation heuristic
- **Different element type → 매 unmount + remount**: `<div>` → `<span>` 매 subtree throw.
- **Same type → 매 props update**: attribute diff 만.
- **Key**: list 의 stable identity — 매 key 없으면 매 index-based, 매 잘못된 reuse.

### 매 2026 alternatives
- **SolidJS signals**: 매 VDOM X — 매 fine-grained dependency tracking. 매 update 가 매 mutation site 직접.
- **Svelte 5 runes**: 매 compile-time reactivity — 매 runtime overhead 최소.
- **Vue 3.5 (Vapor mode)**: 매 VDOM-less compile target — opt-in.
- **React 19 compiler**: 매 manual memoization (useMemo, useCallback) 의 elimination — 매 VDOM 유지하되 매 cost 감소.

### 매 응용
1. **SPA**: React, Preact, Inferno — 매 VDOM 기반.
2. **Server components (RSC)**: 매 server 에서 render → 매 wire format → 매 client hydrate.
3. **Cross-platform**: React Native, Lynx — 매 VDOM 의 platform-agnostic 의 leverage.

## 💻 패턴

### 매 minimal VDOM (educational)
```typescript
type VNode = { type: string; props: Record<string, any>; children: (VNode | string)[] };

function h(type: string, props = {}, ...children: (VNode | string)[]): VNode {
  return { type, props, children };
}

function diff(prev: VNode | null, next: VNode | null, parent: HTMLElement, index = 0) {
  if (!prev) {
    parent.appendChild(render(next!));
  } else if (!next) {
    parent.removeChild(parent.childNodes[index]);
  } else if (prev.type !== next.type) {
    parent.replaceChild(render(next), parent.childNodes[index]);
  } else if (typeof next === "object") {
    updateProps(parent.childNodes[index] as HTMLElement, prev.props, next.props);
    const len = Math.max(prev.children.length, next.children.length);
    for (let i = 0; i < len; i++) {
      diff(prev.children[i] as VNode, next.children[i] as VNode,
           parent.childNodes[index] as HTMLElement, i);
    }
  }
}
```

### 매 React Fiber priority (lanes)
```typescript
import { startTransition, useDeferredValue } from "react";

function SearchBox() {
  const [query, setQuery] = useState("");
  const deferred = useDeferredValue(query);  // 매 low-priority lane

  return (
    <>
      <input value={query} onChange={e => setQuery(e.target.value)} />
      <ExpensiveResults query={deferred} />
    </>
  );
}

// 매 startTransition: 매 non-urgent state update
function tabSwitch(newTab: Tab) {
  startTransition(() => setActiveTab(newTab));
}
```

### 매 key 의 올바른 사용
```tsx
// 매 BAD: index key — 매 reorder 시 매 잘못된 reuse
{items.map((item, i) => <Row key={i} {...item} />)}

// 매 GOOD: stable id
{items.map(item => <Row key={item.id} {...item} />)}

// 매 reorder edge case: 매 form input state 의 보존 의 보장
```

### 매 SolidJS signal (no VDOM)
```tsx
import { createSignal, createMemo, For } from "solid-js";

function Counter() {
  const [count, setCount] = createSignal(0);
  const doubled = createMemo(() => count() * 2);

  // 매 JSX 가 매 reactive primitive 로 compile
  // 매 setCount 호출 시 매 doubled 만 update — 매 component re-render X
  return <button onClick={() => setCount(c => c + 1)}>{doubled()}</button>;
}
```

### 매 React 19 compiler (auto-memo)
```tsx
// 매 React 19 compiler enabled — 매 useMemo / useCallback 불필요
function Parent({ items }: { items: Item[] }) {
  const sorted = items.toSorted((a, b) => a.score - b.score);
  // 매 compiler 가 매 dependency analysis → 매 auto-memo
  return sorted.map(item => <Child key={item.id} item={item} />);
}
```

### 매 RSC (server component)
```tsx
// 매 server component — 매 zero JS shipped
async function ProductPage({ id }: { id: string }) {
  const product = await db.product.findUnique({ where: { id } });
  return (
    <article>
      <h1>{product.name}</h1>
      <ClientCart product={product} />  {/* 매 client island */}
    </article>
  );
}
```

### 매 reconciliation profiling
```tsx
import { Profiler } from "react";

<Profiler id="App" onRender={(id, phase, actualDuration) => {
  if (actualDuration > 16) {
    console.warn(`매 slow render: ${id} took ${actualDuration}ms`);
  }
}}>
  <App />
</Profiler>
```

## 매 결정 기준
| 상황 | Approach |
|---|---|
| 매 large existing React codebase | 매 React 19 + compiler |
| 매 new SPA, performance-critical | 매 SolidJS or Svelte 5 |
| 매 SEO + dynamic | 매 Next.js 15 (RSC) or Remix |
| 매 enterprise, 매 ecosystem 우선 | 매 React (libraries · talent pool) |
| 매 Vue ecosystem 매 lock-in | 매 Vue 3.5 + Vapor mode |

**기본값**: 매 generic web app 매 React 19 + Vite or Next.js 15.

## 🔗 Graph
- 부모: [[DOM]] · [[Reconciliation]]
- 변형: [[React Fiber]]
- 응용: [[Next.js]] · [[Remix]] · [[React Native]] · [[React Server Components]]
- Adjacent: [[SolidJS]] · [[Signals]]

## 🤖 LLM 활용
**언제**: 매 React component 의 generation — 매 LLM 이 매 JSX + hooks 패턴 의 well-trained.
**언제 X**: 매 fiber 의 internal debugging — 매 LLM 의 stale knowledge 의 risk.

## ❌ 안티패턴
- **매 index as key**: 매 list reorder 시 매 wrong state.
- **매 inline object props**: 매 매 render 마다 매 new ref → 매 child memo 무효 (compiler 이전).
- **매 huge component tree**: 매 single render 가 매 thousands node — 매 split 안 함.
- **매 useMemo 남용 (React 19 이전)**: 매 미세 update 의 over-memo — 매 measure 없이 의 cargo cult.
- **매 setState in render**: 매 infinite loop.

## 🧪 검증 / 중복
- Verified (React docs 2026; "React Fiber Architecture" by Andrew Clark; SolidJS docs; Svelte 5 release notes).
- 신뢰도 A.

## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — Fiber, React 19 compiler, signals 비교 추가 |
