가상 DOM은 실제 DOM의 가벼운 JavaScript 표현입니다. Vue는 상태가 변경되면 새 가상 DOM 트리를 만들고, 이전 트리와 비교(diff)하여 최소한의 실제 DOM 조작만 수행합니다.

면접에서 "가상 DOM의 장단점"을 물어보면, 단순히 "빠르다"가 아니라 "DOM 조작을 배치하여 일관된 성능을 보장한다" 라고 설명하는 것이 정확합니다.


VNode (Virtual Node)

TYPESCRIPT
// Vue 내부의 VNode 구조 (간소화)
interface VNode {
  type: string | Component  // 태그명 또는 컴포넌트
  props: Record<string, any> | null
  children: string | VNode[] | null
  key: string | number | null
  el: Node | null           // 실제 DOM 참조
}

// h() 함수로 VNode 생성
import { h } from 'vue'

const vnode = h('div', { class: 'container', id: 'app' }, [
  h('h1', null, 'Hello'),
  h('p', null, 'World')
])

// 결과 VNode 구조
// {
//   type: 'div',
//   props: { class: 'container', id: 'app' },
//   children: [
//     { type: 'h1', props: null, children: 'Hello' },
//     { type: 'p', props: null, children: 'World' }
//   ]
// }

렌더링 파이프라인

PLAINTEXT
1. 컴파일 — 템플릿 → Render Function
2. 마운트 — Render Function → VNode 트리 → 실제 DOM
3. 업데이트 — 새 VNode 트리 → 이전 트리와 diff → Patch (최소 DOM 조작)
PLAINTEXT
템플릿:
<div id="app">
  <p>{{ message }}</p>
</div>

↓ 컴파일

Render Function:
function render() {
  return h('div', { id: 'app' }, [
    h('p', null, message.value)
  ])
}

↓ 실행

VNode 트리 (가상 DOM):
{ type: 'div', props: { id: 'app' }, children: [
  { type: 'p', children: 'Hello' }
]}

↓ Patch

실제 DOM:
<div id="app"><p>Hello</p></div>

Patch 알고리즘

PLAINTEXT
1. 같은 타입 비교:
   - 같은 타입이면 → props 업데이트 + children 재귀 비교
   - 다른 타입이면 → 기존 노드 제거 + 새 노드 생성

2. Children 비교 (keyed diff):
   - key가 있으면 → 이동/재사용 최적화
   - key가 없으면 → 순서대로 비교 (비효율적)

key가 중요한 이유 — 구체적 예시

PLAINTEXT
이전: [A, B, C, D]
이후: [A, D, B, C]  (D가 앞으로 이동)

key 없이:
  B→D (업데이트), C→B (업데이트), D→C (업데이트)
  → 3번의 DOM 업데이트

key 있으면:
  A 유지, D 이동, B 유지, C 유지
  → 1번의 DOM 이동

Vue의 diff 최적화

Vue 3의 컴파일러는 정적 분석을 통해 diff를 최적화합니다.

VUE
<template>
  <div>
    <h1>정적 제목</h1>           <!-- 정적 — diff 건너뜀 -->
    <p>{{ dynamicText }}</p>     <!-- 동적 — diff 대상 -->
    <span class="fixed">고정</span>  <!-- 정적 — diff 건너뜀 -->
  </div>
</template>

컴파일러가 생성하는 코드에는 PatchFlags가 포함됩니다:

  • TEXT — 텍스트만 변할 수 있음
  • CLASS — class 바인딩만 변할 수 있음
  • PROPS — 특정 props만 변할 수 있음

가상 DOM의 장단점

장점단점
선언적 UI — 상태만 변경하면 됨메모리 오버헤드 (VNode 객체)
크로스 플랫폼 (SSR, 네이티브)diff 계산 비용
일관된 성능 (배치 업데이트)극도로 단순한 변경에서는 오버헤드
프레임워크 수준의 최적화Svelte 같은 컴파일 타임 접근보다 느릴 수 있음

면접 팁

  • "가상 DOM이 빠르다"는 절반만 맞습니다. 직접 DOM 조작보다 빠른 것이 아니라, 개발자가 직접 최적화하지 않아도 괜찮은 수준의 성능을 보장 하는 것입니다
  • Vue의 컴파일러 최적화(PatchFlags, 정적 호이스팅)가 React의 가상 DOM과 비교했을 때 어떤 장점이 있는지 설명하면 심화 이해도를 보여줄 수 있습니다
  • key의 역할 을 가상 DOM diff 관점에서 설명하면 v-for의 key가 왜 중요한지 근본적인 답을 할 수 있습니다

요약

가상 DOM은 실제 DOM의 JavaScript 표현으로, diff 알고리즘을 통해 최소한의 DOM 조작만 수행합니다. key는 diff 시 노드를 효율적으로 식별하는 핵심이며, Vue 3의 컴파일러는 PatchFlags와 정적 호이스팅으로 diff 범위를 최소화합니다.

댓글 로딩 중...