--- 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 ( ); } // React 가 매 setCount 시 의 새 vDOM → diff → 매 button text 만 update. ``` ### `key` for stable identity ```jsx function List({ items }) { return ( ); } ``` ### `useMemo` / `React.memo` ```jsx const ExpensiveItem = React.memo(({ item, onClick }) => (
{item.name}
)); 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 => ); } ``` ### Solid (signals, no vDOM) ```jsx import { createSignal } from 'solid-js'; function Counter() { const [count, setCount] = createSignal(0); return ( ); } // 매 specific text node 의 update — 매 component re-render X. ``` ### Svelte (compile-time) ```svelte ``` ### Vue 3 (Proxy-based reactivity + vDOM) ```vue ``` ### htmx (no JS framework) ```html 0 ``` ### 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 ( <> setFilter(e.target.value)} /> ); } ``` ### Performance comparison (React vs Solid) ```ts // 매 typical bench: // React useState + setCount: 매 10K updates → 매 500ms // Solid signal + setCount: 매 10K updates → 매 50ms (10×) ``` ### `` and DOM (no framework) ```html ... ``` ## 매 결정 기준 | 상황 | 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 |