웹 개발을 하다 보면 DOM(Document Object Model) 조작은 필수적입니다.
특히 프론트엔드 라이브러리(React, Vue, Svelte 등)가 등장하면서, 기존 브라우저의 Real DOM 조작과 이를 개선하기 위한 Virtual DOM 개념의 차이가 중요한 논의 주제가 되었습니다.
이번 글에서는 기초적인 DOM 개념부터 시작해서, Virtual DOM이 등장한 이유, 성능 비교, 실제 상황에서의 적용 전략까지 단계적으로 살펴보겠습니다.
Real DOM은 브라우저가 HTML 문서를 해석해 생성하는 트리 구조의 객체 모델입니다.
즉, HTML 태그와 구조를 메모리 상에서 트리 형태로 표현한 것으로, JavaScript를 통해 조작할 수 있습니다.
document
→ html
→ body
→ div
→ span
…document.querySelector()
같은 메서드로 접근/수정 가능Virtual DOM은 브라우저의 DOM을 직접 건드리지 않고, 메모리 상에서 가상의 DOM 트리를 만들어 두고 비교(diffing)한 후 필요한 부분만 Real DOM에 반영하는 방식입니다.
초기 상태:
Real DOM Virtual DOM
<ul> <ul>
<li>A</li> <li>A</li>
<li>B</li> <li>B</li>
<li>C</li> <li>C</li>
</ul> </ul>
업데이트 (C → D):
New Virtual DOM
<ul>
<li>A</li>
<li>B</li>
<li>D</li>
</ul>
Diff 알고리즘 동작:
- A 동일
- B 동일
- C → D 변경
최종 Real DOM 반영:
<ul>
<li>A</li>
<li>B</li>
<li>D</li>
</ul>
➡️ Virtual DOM은 전체를 다시 렌더링하지 않고, 변경된 C → D
만 Real DOM에 반영합니다.
예시: 리스트 1만 개 중 하나를 업데이트해도, 브라우저는 렌더 트리 전체를 다시 계산해야 할 수 있음
<button id="realBtn">Real DOM 업데이트</button>
<ul id="realList"></ul>
<script>
const realList = document.getElementById('realList');
for (let i = 0; i < 10000; i++) {
const li = document.createElement('li');
li.textContent = `Item ${i}`;
realList.appendChild(li);
}
document.getElementById('realBtn').addEventListener('click', () => {
console.time('Real DOM');
for (let i = 0; i < 10000; i++) {
realList.children[i].textContent = `Updated ${i}`;
}
console.timeEnd('Real DOM');
});
</script>
<button id="virtualBtn">Virtual DOM 업데이트</button>
<ul id="virtualList"></ul>
<script>
let vdom = Array.from({ length: 10000 }, (_, i) => `Item ${i}`);
function renderVDOM(vdom) {
const list = document.getElementById('virtualList');
list.innerHTML = vdom.map(item => `<li>${item}</li>`).join('');
}
renderVDOM(vdom);
document.getElementById('virtualBtn').addEventListener('click', () => {
console.time('Virtual DOM');
// 새로운 Virtual DOM 생성
const newVdom = vdom.map((_, i) => `Updated ${i}`);
// Diff & Patch (간단히 모든 항목 비교)
newVdom.forEach((val, i) => {
if (val !== vdom[i]) {
document.getElementById('virtualList').children[i].textContent = val;
}
});
vdom = newVdom;
console.timeEnd('Virtual DOM');
});
</script>
상황 | 권장 방식 |
---|---|
간단한 DOM 조작 (Vanilla JS, jQuery 스타일) | Real DOM 직접 조작 |
대규모 SPA (React, Vue 등) | Virtual DOM 기반 |
고성능 그래픽/UI (게임, 시각화 등) | Canvas, WebGL, 혹은 Fine-grained reactivity 프레임워크 |
마이크로 인터랙션 위주 | Real DOM + 최적화 기법 |