HTML
,XML
문서의 프로그래밍Interface
DOM
은 Document Object Model
의 약자로, HTML
및 XML
문서를 위한 API이다.
DOM
은 객체 간의 관계를 정하지 않은 일종의 논리적 구조이며, 이를 통해 개발자는 문서와 관련된 작업을 수행하며 구조를 탐색할 수 있다.
DOM
을 이해하기 위해서는 데이터 트리 구조(Data Structure Tree)
에 대해 알아야할 필요성이 있다.
데이터 트리 구조
는 자료 구조의 일종으로, 한 노드에서 시작해서 다른 정점들을 순회하여 자기 자신에게 돌아오는 순환이 없는 연결 그래프이다.
트리에서 최상위 노드는 루트 노드(root node)
라고 하며 트리에서 추출할 정보를 검색할 수 있는 공간을 제공한다.
이외에는 부모 노드(parent node)
, 자식 노드(child node)
, 잎 노드(leaf node)
, 내부 노드(internal node)
...등이 각각의 Level
에 속해 구성된다.
모든 Browser
에는 HTML
문서를 DOM
으로 구문 분석하는 DOM Parser
가 존재한다.
DOM Parser
는 HTML
페이지의 데이터를 DOM
을 구성하는 객체로 변환하여 논리적으로 DOM Structure Tree
에 배열한다.
이렇게 생성된 DOM Tree
는 각각의 HTML
요소를 노드(Node)
단위로 구성하며, 이를 통해 HTML
문서에 액세스 및 조작할 수 있다.
만약 DOM Tree
를 통해 노드에 변경 작업을 수행한다면 업데이트 내역이 웹 페이지로 반영된다.
Dom
을 조작하여 데이터를 수정하는 것은 매우 유용한 방법이지만, 문제점 또한 공존한다.
<div>
태그의 색상을 업데이트하는 작업은 해당 DOM node
객체에 접근하지 않은 채 색상 속성만을 업데이트하기 때문에 나머지 트리 노드에는 영향을 미치지 않는다.
하지만 노드를 추가하거나 삭제한다면 이를 통해 웹 페이지 전체의 레이아웃이 영향을 받아 웹페이지의 일부 또는 전체가 다시 리렌더링(Rerendering)
되어 브라우저에서는 많은 시간과 리소스를 소모한다.
이러한 경우를 Reflow
라고 하며, 주로 대화식 사이트(interactive site)
의 업데이트 작업시 발생한다.
대부분의 Browser
에서는 다음과 같은 순서로 Dom
노드 업데이트 작업이 수행된다.
브라우저가 HTML
파일을 수신하면 Render
엔진은 해당 파일을 구문 분석하여 HTML
요소와 일대일 관계를 갖는 Node
의 DOM
트리를 생성한다.
인라인 스타일 구문과 함께 외부 CSS 파일의 스타일이 구문 분석 되어 DOM Tree
의 node
와 함께 Render Tree
를 생성한다.
이 때 Render Tree
가 생성되기 위해서는 Render
객체의 시각적 속성을 계산해야 한다.
그래서 DOM Tree
의 모든 노드에는 계산된 스타일 정보를 가져온 뒤 attach
메서드를 통해 Render
객체를 반환한다.
Render Tree
를 생성한 뒤 화면에 표시될 정확한 위치 좌표를 노드에 제공한다.
Render Tree
가 통과된 뒤 각 노드의 paint
메소드가 호출되어 궁극적으로 화면에 내용이 표시된다.
위 과정을 통해 알 수 있듯 DOM
은 생성할 때마다 Render Tree
의 생성, layout
, painting
...등 모든 과정을 다시 수행해야 한다.
그래서 DOM
은 빠르지만, 브라우저가 수행해야하는 Layout
이 너무 많다는 단점이 존재한다.
이러한 단점을 해결하고자 React
에서는 가상돔(Virtual Dom)
을 사용한다.
React
,Vue.js
및Elm
과 같은 선언적 웹 프레임워크에서 사용되는Document Object Model
의 경량JavaScript
표현
Virtual DOM
은 DOM
을 가볍게 만든 JavaScript
표현이라고 할 수 있으며, 주로 React
, Vue.js
그리고 Elm
에 사용된다.
Virtual DOM
은 실제 DOM
에서 처리하는 방식이 아닌 Virtual DOM
과 메모리에서 미리 처리하고 저장한 후 실제 DOM
과 동기화하는 프로그래밍 개념이다.
즉, 해당 DOM
을 컴포넌트 단위로 쪼개어 HTML
컴포넌트 조립품 처럼 다루는 개념이다.
그래서 DOM
을 직접 업데이트하는 것보다 상대적으로 빠르다.
Dom
과 Virtual DOM
의 특성을 비교하면 다음과 같다.
DOM | Virtual DOM | |
---|---|---|
업데이트 | 느림 | 빠름 |
HTML 업데이트 방식 | 직접적 업데이트 | 직접적 업데이트 안함 |
element 업데이트 방식 | 새로운 DOM 생성 | 새로운 가상 DOM 생성 후 이전 DOM과 비교하여 차이점만 업데이트 |
메모리 | 메모리 낭비가 심함 | 메모리 낭비가 상대적으로 덜함 |
Dom
과 Virtual DOM
을 코드로 비교해보면 다음과 같다.
<ul class="animal">
<li>Lion</li>
<li>Tiger</li>
<li>Dog</li>
</ul>
{
type: "ul",
props: {
"class": "animal"
},
children: [
{
type: "li",
props: null,
children: [
"Lion"
]
},
{
type: "li",
props: null,
children: [
"Tiger"
]
},
{
type: "li",
props: null,
children: [
"Dog"
]
}
]
}
Virtual DOM
은 다음과 같은 순서로 업데이트 작업이 수행된다.
- 데이터가 업데이트 되었을 때, 전체 UI가
Virtual DOM
에서 리랜더링 된다.- 이전
DOM
과 새로운Virtual DOM
의 차이가 계산된다.- 계산이 끝난 후,
DOM
은 변경된 부분만을 변화시킨다.
DOM Standard - whatwg
What, exactly, is the DOM? - bitsofcode
DOM 소개 - Web API | MDN
DOM은 뭐고 가상 DOM은 뭔가요? - 얄팍한 코딩사전