2025-09-22 23:44

  • 가상돔(Virtual DOM)은 실제 DOM 조작의 성능 문제를 해결하기 위해 메모리에 가상의 DOM 트리를 만들고, 변경 사항을 한 번에 효율적으로 실제 DOM에 반영하는 프로그래밍 개념이다.

  • React, Vue.js와 같은 현대적인 자바스크립트 라이브러리 및 프레임워크의 핵심 원리로, 웹 애플리케이션의 속도와 반응성을 크게 향상시킨다.

  • 가상돔은 변경 사항을 감지하는 ‘비교 알고리즘(Diffing Algorithm)‘과 변경된 부분만 실제 DOM에 적용하는 ‘재조정(Reconciliation)’ 과정을 통해 불필요한 렌더링을 최소화하고 개발 경험을 개선한다.

가상돔 완벽 정복 핸드북 DOM을 넘어선 웹 혁신

웹 개발의 패러다임을 바꾼 가상돔(Virtual DOM). React, Vue.js와 같은 현대적인 프레임워크를 이해하기 위한 핵심 개념이지만, 많은 개발자가 그저 ‘빠르다’라고만 알고 있을 뿐, 내부 동작 원리나 탄생 배경에 대해서는 깊이 알지 못한다. 이 핸드북은 가상돔의 탄생 비화부터 구조, 작동 방식, 그리고 심화 주제까지 모든 것을 파헤쳐 웹 개발의 깊이를 더해줄 완벽한 안내서다.

1. 가상돔은 왜 세상에 나왔을까 문제 해결사로서의 탄생

가상돔의 등장을 이해하려면 먼저 전통적인 DOM(Document Object Model) 조작 방식의 한계를 알아야 한다. DOM은 웹 브라우저가 HTML 문서를 해석하여 만든 객체 트리 모델이다. 자바스크립트는 이 DOM을 통해 문서의 구조, 스타일, 내용 등을 변경하며 동적인 웹 페이지를 만든다.

문제는 DOM 조작이 ‘비싼’ 작업이라는 점이다. DOM 요소에 작은 변화 하나만 생겨도 브라우저는 해당 요소와 그 자식 요소들의 스타일을 다시 계산하고(Reflow), 화면에 다시 그리는(Repaint) 과정을 거친다. 이 과정은 상당한 컴퓨팅 자원을 소모하며, 특히 복잡하고 동적인 애플리케이션에서는 잦은 DOM 변경으로 인해 심각한 성능 저하를 유발했다.

예를 들어, 100개의 리스트 아이템 중 하나만 내용이 바뀌어도, 최악의 경우 100개 아이템 전체에 대한 레이아웃 계산과 렌더링이 다시 일어날 수 있다. 개발자들은 이러한 비효율을 피하기 위해 변경이 필요한 DOM 요소만 정확히 찾아내어 최소한으로 조작하는 코드를 직접 작성해야 했다. 이는 매우 번거롭고 오류가 발생하기 쉬운 작업이었다.

이러한 배경 속에서 “DOM 조작을 직접 하지 말고, 변화가 있을 때마다 전체 UI를 새로 그린다는 개념으로 접근하되, 성능은 유지할 수 없을까?” 라는 혁신적인 아이디어가 등장했다. 이 아이디어를 현실로 만든 것이 바로 가상돔이다. 가상돔은 실제 DOM을 직접 건드리는 대신, 메모리상에 존재하는 가벼운 자바스크립트 객체 형태의 ‘가상’ DOM을 만들어 개발자가 DOM 상태 관리의 부담을 덜고 비즈니스 로직에 집중할 수 있도록 돕는다.

2. 가상돔의 구조 해부 자바스크립트 객체의 마법

가상돔은 이름에 ‘돔’이 들어가지만 실제 DOM이 아니다. 본질적으로 **실제 DOM의 구조를 흉내 낸 자바스크립트 객체(JavaScript Object)**에 불과하다. 이 객체는 실제 DOM이 가진 복잡한 속성이나 API 없이, 오직 UI를 렌더링하는 데 필요한 최소한의 정보(태그 종류, 속성, 자식 요소 등)만을 담고 있다.

다음은 간단한 HTML 구조와 그에 해당하는 가상돔 객체를 비교한 예시다.

HTML 구조:

HTML

<div id="app">
  <h1 class="title">Hello World</h1>
  <p>This is a paragraph.</p>
</div>

가상돔 객체 표현:

JavaScript

{
  type: 'div',
  props: { id: 'app' },
  children: [
    {
      type: 'h1',
      props: { className: 'title' },
      children: 'Hello World'
    },
    {
      type: 'p',
      props: {},
      children: 'This is a paragraph.'
    }
  ]
}

이처럼 가상돔은 실제 DOM보다 훨씬 가볍고, 브라우저의 렌더링 엔진에 직접 접근하지 않기 때문에 생성하고 조작하는 비용이 매우 저렴하다. 개발자는 상태(State)가 변경될 때마다 이 가상돔 객체를 새로 생성하기만 하면 된다. 실제 DOM을 어떻게 효율적으로 업데이트할지에 대한 고민은 가상돔을 관리하는 라이브러리(React 등)가 대신 처리해준다.

3. 가상돔의 작동 원리 비교와 재조정의 예술

가상돔의 진정한 마법은 상태가 변경되었을 때 일어나는 일련의 과정에서 발휘된다. 이 과정은 크게 세 단계로 나눌 수 있다.

  1. 상태 변경 및 새로운 가상돔 트리 생성: 사용자의 입력이나 데이터 변경 등 애플리케이션의 상태(State)에 변화가 발생한다. 그러면 해당 상태를 기반으로 새로운 가상돔 트리가 통째로 다시 만들어진다. 이 과정은 메모리 안에서만 일어나므로 매우 빠르다.

  2. 비교 알고리즘 (Diffing Algorithm): 이제 라이브러리는 이전 가상돔 트리(업데이트 전 스냅샷)와 새로 만들어진 가상돔 트리를 비교하여 어떤 부분이 바뀌었는지 찾아낸다. 이 비교 과정을 ‘Diffing’이라고 한다.

  3. 재조정 (Reconciliation): 비교 알고리즘을 통해 발견된 변경 사항들(예: ‘h1’ 태그의 텍스트 변경, ‘p’ 태그 삭제 등)을 모아 실제 DOM에 한 번에(Batch Update) 적용한다. 이 과정에서 변경이 필요한 최소한의 부분만 건드리기 때문에 불필요한 Reflow와 Repaint를 방지하고 성능을 최적화할 수 있다.

핵심은 비교 알고리즘

가상돔의 성능을 좌우하는 것은 바로 이 ‘비교 알고리즘’이다. 두 개의 트리를 비교하는 일반적인 알고리즘은 의 복잡도를 가지지만, React와 같은 라이브러리는 다음과 같은 휴리스틱(Heuristic) 가정을 통해 O(n) 수준으로 복잡도를 획기적으로 낮췄다.

  • 다른 타입의 두 요소는 다른 트리를 생성한다: <div>에서 <p>로 요소 타입이 변경되면, 이전 트리를 완전히 버리고 새로운 트리를 처음부터 구축한다.

  • 개발자가 key 속성을 통해 어떤 자식 요소가 변경되지 않았는지 표시해 줄 수 있다: 리스트 렌더링 시 각 아이템에 고유한 key를 부여하면, React는 key를 통해 이전 트리와 현재 트리의 자식 요소가 동일한지 아닌지를 효율적으로 비교할 수 있다. key가 없다면 리스트의 순서가 바뀌거나 중간에 요소가 삽입될 경우, 모든 자식 요소를 변경된 것으로 간주하여 비효율적인 업데이트가 발생할 수 있다.

이러한 과정을 통해 가상돔은 “일단 전부 다시 그리고, 바뀐 부분만 진짜 DOM에 알려주자”는 단순하면서도 강력한 아이디어를 현실로 구현한다.

4. 가상돔 사용법 개발자는 무엇을 해야 할까?

가상돔을 사용하는 개발자는 가상돔의 내부 동작을 하나하나 신경 쓸 필요가 없다. 대신, 애플리케이션의 **상태(State)**가 주어졌을 때 UI가 어떻게 보여야 하는지를 선언적으로(Declaratively) 정의하는 데 집중하면 된다.

React를 예로 들어보자.

JavaScript

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

위 코드에서 개발자는 count라는 상태와 이 상태가 변할 때 UI가 어떻게 렌더링되어야 하는지를 JSX를 통해 선언적으로 작성했다.

  1. button을 클릭하면 setCount 함수가 호출되어 count 상태가 변경된다.

  2. React는 count 상태 변경을 감지하고 Counter 컴포넌트를 다시 실행하여 새로운 가상돔 트리를 생성한다.

  3. 이전 가상돔 트리 (<h1>Count: 0</h1>)와 새로운 가상돔 트리 (<h1>Count: 1</h1>)를 비교한다.

  4. 비교 결과 <h1> 태그 내부의 텍스트만 ‘0’에서 ‘1’로 변경된 것을 확인한다.

  5. 이 변경 사항을 실제 DOM에 적용한다.

개발자는 오직 상태(count)와 그 상태를 변경하는 로직(setCount)에만 집중했을 뿐, 어떤 DOM 요소를 찾아 어떻게 바꿔야 하는지에 대한 코드는 전혀 작성하지 않았다. 이처럼 가상돔은 개발 경험을 크게 향상시키고 코드의 예측 가능성을 높여준다.

5. 심화 내용 가상돔을 넘어서

가상돔은 웹 개발에 혁신을 가져왔지만, 은탄환은 아니다. 가상돔 자체도 메모리를 차지하고 비교 알고리즘을 실행하는 데 비용이 든다. 이 때문에 최근에는 가상돔의 단점을 보완하려는 새로운 시도들이 등장하고 있다.

기술접근 방식장점단점주요 프레임워크/라이브러리
가상돔메모리 내 가상 트리를 통해 변경 사항을 비교하고 일괄적으로 실제 DOM에 적용.선언적 UI 개발, 복잡한 앱에서의 성능 향상, 플랫폼 간 호환성(React Native)메모리 사용량, 비교 과정의 오버헤드React, Vue.js
컴파일 기반빌드 시점에 코드를 분석하여 변경될 수 있는 부분을 정확히 파악하고, 해당 부분만 직접 조작하는 코드를 생성.가상돔 없음(런타임 오버헤드 최소화), 매우 빠른 초기 로딩 및 업데이트 속도프레임워크의 마법에 대한 의존도 증가, 상대적으로 작은 생태계Svelte, SolidJS

Svelte와 같은 프레임워크는 가상돔을 아예 사용하지 않는다. 대신, 코드를 컴파일하는 단계에서 어떤 상태가 변하면 어떤 DOM이 업데이트되어야 하는지를 미리 파악하여 매우 최적화된 자바스크립트 코드를 생성한다. 이는 런타임에 가상돔을 비교하는 과정 자체를 없애므로 더 빠른 속도를 보여주기도 한다.

하지만 가상돔은 여전히 강력하며, 특히 애플리케이션의 규모가 크고 상태 변화가 복잡할수록 그 진가를 발휘한다. 또한 React Native처럼 웹을 넘어 다른 플랫폼까지 코드를 확장할 수 있게 해주는 중요한 기반이기도 하다.

결론 가상돔, 단순한 기술을 넘어선 철학

가상돔은 단순히 웹 페이지를 빠르게 만드는 기술을 넘어, 개발자가 UI를 어떻게 바라보고 만들어야 하는지에 대한 철학을 담고 있다. 복잡한 DOM 조작 명령을 내리는 대신, “상태가 이러하면, UI는 이러해야 한다”고 선언하는 방식으로 개발의 패러다임을 전환했다.

이 핸드북을 통해 가상돔의 탄생 배경부터 내부 동작 원리, 그리고 최신 동향까지 깊이 있게 이해했기를 바란다. 가상돔을 제대로 이해하는 것은 현대 웹 개발의 핵심을 꿰뚫는 것이며, 더 나은 성능과 유지보수성을 갖춘 애플리케이션을 만드는 견고한 토대가 될 것이다.