DOM이란 Document Object Model (문서객체모델)의 약어이다. 웹 페이지는 일종의 문서(document)로 웹 페이지를 수정하거나 생성하는데 사용되는 모든 속성, 메서드, 이벤트 들은 objects로 구성된다.
이 DOM을 통해 JavaScript와 같은 스크립트 언어는 웹 페이지의 요소들에 접근하고 조작할 수 있다.
(다시 말해, JavaScript만 DOM을 조작할 수 있는 건 아니다. PHP도, Java도 심지어 Python도 조작할 수 있다.)
Virtual DOM없는 웹 페이지의 렌더링 과정을 보면
HTML 다운로드 및 파싱:
브라우저는 웹 페이지의 HTML 파일을 다운로드하고, 이를 파싱하여 DOM 트리를 생성한다. DOM 트리는 웹 페이지의 구조화된 표현으로, HTML 요소, 속성, 텍스트 등이 노드로 표현된다.
CSS 다운로드 및 파싱:
브라우저는 CSS 파일을 다운로드하고, 이를 파싱하여 CSSOM(CSS Object Model)을 생성한다. CSSOM은 CSS 규칙, 스타일 정보 등을 표현하는 객체로, DOM 트리와 결합되어 웹 페이지의 시각적 표현을 생성한다.
Render 트리 생성:
DOM 트리와 CSSOM을 결합하여 Render 트리를 생성한다. Render 트리는 화면에 표시되는 실제 요소들로 구성되며, 렌더링 엔진은 이를 기반으로 레이아웃과 페인팅을 수행한다.
레이아웃(Layout):
레이아웃 단계에서는 Render 트리의 각 요소의 위치와 크기를 계산한다. 이를 통해 요소들의 배치와 상호 간섭을 결정하고, 화면에 어떻게 배치되는지를 결정한다.
페인팅(Painting):
페인팅 단계에서는 Render 트리의 각 요소에 대해 실제 픽셀을 그리는 작업을 수행한다. 요소의 스타일, 배경, 텍스트 등이 실제로 화면에 표시된다.
여기까지만 보면 왜 굳이 있는 DOM을 다른 걸로 사용하나 할 수 있다.
제일 큰 문제는 바로 성능 관련된 부분이다.
DOM은 웹 페이지의 구조를 표현하는 트리 구조이기 때문에, 웹 페이지의 요소가 많아질수록 DOM 조작은 느려질 수 있다. 또한 DOM 조작이 발생하면 브라우저는 다시 레이아웃을 계산하고, 페인팅을 수행해야 한다. 즉 변경사항이 있을때마다 렌더링을 다시 하는 것이다.(위의 과정에서는 3~5번 부분)
Virtual DOM(가상 DOM)은 실제 DOM과 유사한 메모리 상의 가상 트리 구조이다. Virtual DOM을 사용하면 개발자는 실제 DOM을 직접 조작하는 대신 상태 변경에 따라 가상 DOM을 업데이트할 수 있다.
React와 Vue가 Virtual DOM에 기반한 것에 비해 Angular는 Incremental DOM을 사용한다.
Incremental DOM은 렌더 트리의 변경점을 찾을 때 실제 DOM을 사용한다.
간단하게 장단점만 짚어보자면 Incremental DOM은 Virtual DOM에 비해 메모리 점유율이 낮다. 하지만 속도가 상대적으로 느리다.
참고: https://ui.toast.com/posts/ko_20210819