Files
2nd/10_Wiki/Topics/AI_and_ML/DOM vs Virtual DOM.md
T
Antigravity Agent f8b21af4be Wiki cleanup: error-doc removal, dedup merge, link normalization
10_Wiki/Topics 대규모 정리:
- 오류 캡처/미완성 stub 문서 227개 제거
- 교차폴더 중복 43클러스터 병합 (63파일 → redirect)
- 링크명 정규화: 깨진 링크 수정·redirect 직결·개념 매핑 ~2,400건
- 카테고리 MOC 6개 신규 생성
- Graph 섹션 미해결 related-keyword 링크 10,058건 제거

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 23:52:15 +09:00

275 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: wiki-2026-0508-dom-vs-virtual-dom
title: DOM vs Virtual DOM
category: 10_Wiki/Topics
status: verified
canonical_id: self
aliases: [DOM, Virtual DOM, vDOM, reconciliation, diffing, React fiber, Solid signals, Svelte compile]
duplicate_of: none
source_trust_level: A
confidence_score: 0.93
verification_status: applied
tags: [frontend, dom, virtual-dom, react, fiber, solid, svelte, signals, fine-grained-reactivity]
raw_sources: []
last_reinforced: 2026-05-10
github_commit: pending
tech_stack:
language: JavaScript / React / Solid / Svelte
framework: React / Solid / Svelte / Vue
---
# DOM vs Virtual DOM
## 매 한 줄
> **"매 DOM mutation 의 expensive — 매 abstraction 의 batch"**. React 의 Virtual DOM (2013). 매 modern: 매 fine-grained reactivity (Solid, Svelte, Vue 3) 의 vDOM 의 supersede 의 trend. 매 pure DOM (vanilla, htmx) 의 revival.
## 매 핵심
### Real DOM
- 매 browser 의 tree.
- 매 mutation 의 reflow / repaint 의 trigger.
- 매 manual update 의 error-prone.
### Virtual DOM (React)
- 매 lightweight JS object 의 in-memory.
- 매 declarative state.
- 매 diff + 매 reconciliation 의 minimal real DOM update.
### 매 React 의 algorithm
1. 매 새 Virtual DOM tree.
2. 매 diff vs 매 previous (heuristic O(n)).
3. 매 minimal real DOM mutation.
### 매 React 의 heuristic
- **Different type** → 매 entirely new tree.
- **`key` attribute** → 매 stable child identity.
- **Component type same + props different** → 매 update only changed.
### 매 modern alternative
#### Fine-grained reactivity (Solid, Svelte 5, Vue 3)
- 매 vDOM 의 X.
- 매 signal / effect 의 specific DOM 의 update.
- 매 faster + smaller bundle.
#### Compile-time (Svelte)
- 매 framework 의 compile away.
- 매 매 component 의 specific imperative code.
#### htmx / Pure HTML
- 매 server-side render + 매 partial swap.
- 매 매 minimum JS.
### 매 trade-off
| 측면 | Real DOM | Virtual DOM | Fine-grained |
|---|---|---|---|
| Direct manipulation | Manual | Abstracted | Abstracted |
| Update granularity | Per-mutation | Per-component | Per-signal |
| Memory | Low | Medium | Low |
| Bundle size | Tiny | 50KB+ (React) | <10KB (Solid) |
| Rendering speed | Variable | Good | Best |
| Mental model | Imperative | Declarative + render fn | Declarative + signals |
### 매 React Fiber (2017)
- 매 reconciliation 의 interruptible.
- 매 priority-based.
- 매 concurrent rendering.
- 매 React 18+ default.
### 매 modern React 18+ optimization
- **Concurrent rendering**: 매 interrupt.
- **Automatic batching**.
- **Suspense + streaming**.
- **`useTransition` / `useDeferredValue`**.
- **RSC** (Server Components).
### 매 응용
1. **Large dynamic UI**: React / Solid.
2. **Static + light interactivity**: htmx / Astro islands.
3. **Form-heavy**: Solid (fast).
4. **SEO-critical**: Next.js (SSR).
5. **Data viz**: D3 + minimal framework.
## 💻 패턴
### React (declarative)
```jsx
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
// React 가 매 setCount 시 의 새 vDOM → diff → 매 button text 만 update.
```
### `key` for stable identity
```jsx
function List({ items }) {
return (
<ul>
{items.map(item => (
<li key={item.id}>{item.name}</li> // 매 key 의 stable identity
))}
</ul>
);
}
```
### `useMemo` / `React.memo`
```jsx
const ExpensiveItem = React.memo(({ item, onClick }) => (
<div onClick={onClick}>{item.name}</div>
));
function List({ items, onSelect }) {
// 매 stable callback for memoization
const handleSelect = useCallback((id) => onSelect(id), [onSelect]);
const sorted = useMemo(() =>
items.sort((a, b) => a.priority - b.priority), [items]);
return sorted.map(item =>
<ExpensiveItem key={item.id} item={item} onClick={handleSelect} />
);
}
```
### Solid (signals, no vDOM)
```jsx
import { createSignal } from 'solid-js';
function Counter() {
const [count, setCount] = createSignal(0);
return (
<button onClick={() => setCount(count() + 1)}>
Count: {count()}
</button>
);
}
// 매 specific text node 의 update — 매 component re-render X.
```
### Svelte (compile-time)
```svelte
<script>
let count = 0;
</script>
<button on:click={() => count++}>
Count: {count}
</button>
<!-- 매 compile 의 imperative code 의 generate -->
```
### Vue 3 (Proxy-based reactivity + vDOM)
```vue
<script setup>
import { ref } from 'vue';
const count = ref(0);
</script>
<template>
<button @click="count++">Count: {{ count }}</button>
</template>
```
### htmx (no JS framework)
```html
<button hx-post="/click" hx-target="#count" hx-swap="innerHTML">
Click me
</button>
<span id="count">0</span>
<!-- 매 server 가 매 HTML 의 return → 매 swap -->
```
### Direct DOM (vanilla)
```js
const button = document.querySelector('button');
let count = 0;
button.addEventListener('click', () => {
count++;
button.textContent = `Count: ${count}`; // 매 direct mutation
});
```
### Concurrent rendering (React 18+)
```jsx
import { useTransition, useDeferredValue } from 'react';
function SearchableList({ items }) {
const [filter, setFilter] = useState('');
const deferred = useDeferredValue(filter);
const filtered = items.filter(i => i.name.includes(deferred));
return (
<>
<input value={filter} onChange={e => setFilter(e.target.value)} />
<List items={filtered} />
</>
);
}
```
### Performance comparison (React vs Solid)
```ts
// 매 typical bench:
// React useState + setCount: 매 10K updates → 매 500ms
// Solid signal + setCount: 매 10K updates → 매 50ms (10×)
```
### `<picture>` and DOM (no framework)
```html
<picture>
<source srcset="/img.avif" type="image/avif">
<img src="/img.jpg" alt="..." width="800" height="600">
</picture>
<!-- 매 HTML primitive 의 사용 -->
```
## 매 결정 기준
| 상황 | Approach |
|---|---|
| Large dynamic SPA | React + Concurrent |
| Performance-critical | Solid / Svelte |
| SEO + static + light JS | Astro + Islands |
| Form-heavy | Solid |
| Server-driven | htmx + HTML |
| Data viz | D3 + minimal |
| Vanilla / lib-free | Direct DOM |
**기본값**: React for ecosystem. Solid / Svelte for performance.
## 🔗 Graph
- 부모: [[Frontend]] · [[Web-Performance]] · [[React]]
- 변형: [[Virtual-DOM]] · [[Fine-Grained-Reactivity]]
- 응용: [[React]] · [[Solid]] · [[Vue-3]] · [[htmx]] · [[Astro]]
- Adjacent: [[Critical_Rendering_Path]] · [[CSS Animations]] · [[Core Web Vitals Optimization (INP, LCP 개선)]] · [[Container_Queries]]
## 🤖 LLM 활용
**언제**: 매 framework selection. 매 perf optimization. 매 bundle size 의 reduce.
**언제 X**: 매 backend (다른 paradigm).
## ❌ 안티패턴
- **Direct DOM mutation in React**: 매 desync.
- **`key={index}` for dynamic list**: 매 wrong reconciliation.
- **No memoization (heavy re-render)**: 매 perf.
- **Premature memoization**: 매 over-engineering.
- **vDOM 의 large overhead** (small list): 매 vanilla 의 더 빠름.
## 🧪 검증 / 중복
- Verified (React docs, Solid docs, Svelte performance benchmark).
- 신뢰도 A.
- Related: [[Critical_Rendering_Path]] · [[CSS Animations]] · [[Core Web Vitals Optimization (INP, LCP 개선)]] · [[Container_Queries]] · [[Case-Study-Allbirds-PWA-Redesign]].
## 🕓 Changelog
| 날짜 | 변경 |
|---|---|
| 2026-05-08 | Phase 1 |
| 2026-05-10 | Manual cleanup — DOM vs vDOM vs fine-grained + 매 React / Solid / Svelte / htmx code |