Notice
Recent Posts
Recent Comments
Link
«   2026/07   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

mimizae 님의 블로그

Virtual DOM이란? 본문

FE

Virtual DOM이란?

mimizae 2025. 11. 7. 19:17

 

DOM이란?

Virtual DOM에 대해 알아보기 전에 DOM이 무엇인지부터 알아보고 시작하자.

 

MDN에서 정의한 DOM이란...

문서 객체 모델(The Document Object Model, 이하 DOM) 은 HTML, XML 문서의 프로그래밍 interface이다.
DOM은 문서의 구조화된 표현(structured representation)을 제공하며 프로그래밍 언어가 DOM 구조에 접근할 수 있는 방법을 제공하여 그들이 문서 구조, 스타일, 내용 등을 변경할 수 있게 돕는다.
DOM 은 nodes와 objects로 문서를 표현한다. 이들은 웹 페이지를 스크립트 또는 프로그래밍 언어들에서 사용될 수 있게 연결시켜주는 역할을 담당한다.

 

MDN에서의 DOM 정의를 발췌했다!

 

(이미 쉽게 설명한 거겠지만... 😅) 이 정의를 조금만 더 풀어서 말하자면, 문서 객체 모델(DOM)은 HTML 문서 구조를 객체로 표현한 것이라고 할 수 있겠다.

 

HTML 문서에는 <body>, <p> 같은 여러 태그들이 계층적으로 구성되어 있다.

계층 구조를 그대로 반영해 만든 객체 트리가 바로 DOM이다.

 

이렇게 HTML 문서를 객체로 표현하면 JavaScript 같은 스크립트 언어가 웹페이지의 구조나 내용에 접근하고 조작할 수 있게 된다.

 

즉, DOM은 HTML로 구성된 웹 페이지와 스크립트 및 프로그래밍 언어를 연결시켜주는 Interface 역할을 하는 것이다!

 


Virtual DOM의 등장 배경

오케이!! DOM이 뭔지는 알겠는데, 웬 Virtual DOM? 싶을 것이다.

 

이건 먼저 브라우저의 웹 페이지 렌더링 과정을 알아야하는데, 이 과정에 대해 간단히!!!! 말하자면

브라우저는 HTML을 처음 읽고 나서 다음과 같은 단계를 거친다.

 

1. HTML 파싱 → DOM 트리 생성 

브라우저가 HTML 코드를 해석해, 문서 구조를 객체 형태의 트리(DOM)로 표현한다.

 

2. CSS 파싱 → CSSOM 생성

외부 CSS 파일이나 <style> 태그를 읽어, 스타일 정보를 객체 모델로 만든다.

 

3. DOM + CSSOM → Render Tree 생성

두 트리를 결합해, 화면에 실제로 표시될 요소들만 포함한 Render Tree를 만든다. (display: none가 적용된 요소 등은 제외 됨)

 

4. Layout(Reflow) 

각 요소의 위치와 크기를 계산한다.

 

5. Paint(Repaint)

계산된 Render Tree를 바탕으로 픽셀을 그려 화면에 표시한다.

 

 

만약, 이렇게 만들어진 웹 페이지에 변경이 일어난다면?

 

그 변경이 색상 변경이나 크기 조정처럼 단순한 스타일 변경이라면 비교적 가볍다.

하지만 요소의 추가, 삭제, 이동처럼 DOM 구조 자체가 바뀌는 경우, 브라우저는 다음 과정을 반복해서 수행해야 한다.

 

  1. 변경된 부분을 반영하기 위해 렌더 트리(Render Tree) 를 다시 계산하고
  2. 그에 따라 레이아웃(Layout, Reflow) 을 재수행하며
  3. 다시 화면을 그리는(Paint, Repaint) 작업을 한다.

 

웹 페이지가 단순해서 변경될 만한 요소가 많이 없는 정적인 문서라면 크게 문제가 되지는 않겠지만, 현대의 웹 페이지는 대부분 동적이다.

 

버튼 클릭, 탭 전환, 애니메이션, 데이터 갱신 등으로 DOM 구조가 자주 바뀌는 동적인 웹 페이지일 수록

브라우저가 렌더 트리를 다시 만들고 화면을 새로 그리는 빈도가 높아지고 렌더링 비용이 누적되어 성능이 크게!!!!!! 저하된다.

 

 

그렇기에 실제 DOM 조작(변경)을 최소화하는 것이 중요해졌고, React는 이를 최소화 하기 위한 방법으로 Virtual DOM을 도입했다.


Virtual DOM의 동작 원리

 

React는 렌더링이 발생될 상황(state 변화, props 변화, 부모 컴포넌트 렌더링, context 값 변화 등)에 놓이게 되면

새로운 화면에 들어갈 내용이 담긴 Virtual DOM을 생성하게 된다.

 

 

Virtual DOM은 실제 DOM의 가벼운 복사본으로 React 메모리 상에 존재하며, JavaScript 객체 형태로 존재한다.


 

엥? JavaScript 객체 형태로 존재한다니?

 

이런 HTML이 있다고 가정해 보자.

<div id="root">
  <h1>Hello</h1>
  <p>World</p>
</div>

 

 

 

브라우저가 이 HTML을 파싱해서 DOM 트리로 만든다면, 브라우저 메모리 내부에서는 이렇게 복잡하게 저장된다.

HTMLDivElement
 ┣ HTMLElement (h1)
 ┗ HTMLElement (p)

 

이때, 각 노드는 내부적으로 많은 프로퍼티(CSS, 이벤트, geometry, layout 등)를 가지고 있어서 무거운 객체이다.

 

 

하지만 브라우저와 달리 React는 위 HTML을 JavaScript 객체로 무겁지 않게, 아래와 같이 단순하게 표현한다.

const virtualDOM = {
  type: "div",
  props: {
    id: "root",
    children: [
      { type: "h1", props: { children: "Hello" } },
      { type: "p", props: { children: "World" } }
    ]
  }
};

 

즉, Virtual DOM은 실제 HTMLDivElement가 아니라 "이 DOM은 이런 구조야" 를 표현하는 순수 자바스크립트 객체이다!

이 객체는 브라우저 엔진이 아닌 React 메모리 안에 존재한다.

 


 

React는 항상 렌더링 이전의 화면 구조렌더링 이후의 화면 구조를 가진 두 개의 Virtual DOM 객체를 유지하고 있다.

 

변경이 일어난다면, React는 메모리 안에서 Virtual DOM끼리 비교(diff)해서 어떤 부분이 실제로 바뀌었는지를 계산을 한다.

(React는 어디를 바꿔야 할지를 찾아내는 두뇌 역할이랄까...)

 

React가 찾은 변경점만 실제 DOM API를 통해 브라우저에게 전달한다. 그러면 브라우저는 그 부분만 실제 화면에서 업데이트하고,
그때 렌더 트리 재계산 → reflow → repaint 같은 과정을 수행한다.

 

즉, React의 Virtual DOM은 브라우저가 업데이트가 필요 없는 부분은 건드리지 않게끔 조정해준다!

 

 

 

Virtual DOM끼리 비교될 때 React가 사용하는 diffing 알고리즘의 동작 방식을 간단하게 알아보자면,

  • 이전 Virtual DOM 트리와 새로운 Virtual DOM 트리를 비교하고 루트 노드에서 시작해서 이전과 새로운 노드를 비교한다.
  • 두 노드가 다른 유형이면 새 노드를 생성하여 기존 노드를 대체한다.
  • 두 노드가 같은 유형이면 속성을 비교해서 변경된 것이 있는지 확인하고 변경된 속성이 없으면 그대로 사용하고 있으면 속성을 업데이트한다.
  • 이렇게 해서 자식노드를 재귀적으로 비교한다.

이 알고리즘은 두 Virtual DOM 트리를 효율적으로 비교하여 어떤 요소가 변경되었는지를 정확히!! 파악한다.

 

 

이렇게 변경점을 찾아내고 실제 DOM에 반영하는 위의 전체 과정을 React에서는 재조정(reconciliation) 이라고 부른다.


그럼... Virtual DOM을 쓰면 무조건 성능 향상?

NO!! 💢 무조건, 항상 그런 것은 아니다.

 

데이터가 지속적으로 변화하는 동적인 애플리케이션에서는 Virtual DOM을 사용했을 때 성능 향상이 큰 편이지만, 데이터가 자주 변경되지 않는 정적인 애플리케이션에서는 오히려 성능이 느려질 수도 있다.

 

예를 들어, 정보 제공만 하는 웹 페이지라면 아무런 인터렉션이 발생하지 않기 때문에 DOM tree의 변화가 발생하지 않아서, 일반 DOM의 성능이 더 좋을 수 있다!

 

그리고 실제 Virtual DOM의 diff 알고리즘이 빠르긴 하지만 추가적인 비용이 발생하기 때문에 필요에 맞게 도입을 해야한다.


 

이 부분은 내가 헷갈렸던 부분인데... 살짝 부끄럽지만 혹시 이렇게 헷갈릴 0명을 위해 공유한다...

(나는 Virtual DOM과 렌더 트리의 사이를 너무 깊생했다;;)

 

Virtual DOM을 도입한다고 브라우저의 렌더 트리가 전체 재계산을 안 하는 게 아니고,

React 단에서 Virtual DOM과 diff 알고리즘을 통해 브라우저는 여전히 렌더 트리 재계산을 하지만 그 빈도와 범위를 최소화!!!!!!!!하도록 조정해 주는 것이다.

 

기존(바닐라 JS, jQuery 등)

  1. JS가 DOM 직접 수정
    → element.appendChild(newNode)
  2. 브라우저가 '어? 구조 바뀌었네?' 감지
    → Render Tree 다시 계산
  3. Reflow / Repaint 발생
    → 필요 시 레이아웃 전부 다시 계산 
  • 개발자가 직접 여러 번 DOM을 바꾸면 그때마다 브라우저가 렌더 트리를 계속 다시 만듦 → 비효율적

 

React (Virtual DOM 사용 시)

  1. 상태 변경 → React가 새 Virtual DOM 생성
  2. React가 이전 Virtual DOM과 비교(diff)
  3. 변경된 노드만 실제 DOM에 1회로 묶어서 반영 (Batching)
  4. 그제서야 브라우저가 렌더 트리 일부 재계산

브라우저 입장에서는 작은 DOM 변경 여러 번 → 한 번에 모은 최적화된 DOM 변경으로 줄어듦.
즉, 렌더 트리 재계산은 여전히 일어나지만 최소화되는 것!

 

결론적으로 정리하자면...

 

  • Virtual DOM은 렌더 트리 재계산을 없애는 게 아니라, 최소한으로 줄이는 게 목적.
  • 브라우저는 여전히 Render Tree / Reflow / Repaint를 수행하지만, React가 변경을 묶어서 전달하므로 훨씬 적게 일어난다!
  • 즉, Virtual DOM이 브라우저의 렌더링 엔진을 대체하는 게 아니라, 렌더 트리 갱신을 최소화하도록 하는 중간 완충재!

참고 자료

https://ko.legacy.reactjs.org/docs/faq-internals.html

https://wikidocs.net/273873

https://nayoungkim00.tistory.com/44

https://velog.io/@ye-ji/DOM-vs-Virtual-DOM

https://velog.io/@ksykma/React-Virtual-DOM%EC%9D%B4%EB%9E%80

https://developer.mozilla.org/ko/docs/conflicting/Web/API/Document_Object_Model_a0b90593de4c5cb214690e823be115a18d605d4bc7719ba296e212da2abe18ef

https://docs.tosspayments.com/resources/glossary/dom

https://yong-nyong.tistory.com/80

'FE' 카테고리의 다른 글

낙관적 업데이트 적용하기  (0) 2025.12.05
스크롤 감지 Tab-Bar 구현하기  (0) 2025.11.26
실시간 알림 구현하기  (0) 2025.11.16
SEO에 대한 고찰  (2) 2025.10.16
aws lambda로 이미지 리사이징 기능 구현하기  (0) 2025.10.12