V-DOM ( Virtual DOM )
시작하기 전 앞서, 현대 Front-end 프레임워크에서 많이 사용하고 있는 V-DOM
에 대해서 알아봅시다.
DOM : Document Object Model
위에 보시는 것 처럼, DOM
이란놈이 우리가 사용하는 HTML문서에 대하여 구조적인 표현방법을 제공합니다.
이 DOM
은,
- Cross-Platform, Cross-Browser
- Web page 구조 쉽게
- Control 할 수 있는 API 제공
- Manipulation 에서 다소 느리다 라는 특징이 있습니다.
기본적으로 Browser는, reflow나 repaint를 최대한 최적화 하여 동작합니다.
하지만, 다음과 같은 경우에 최적화를 무력화 시키는 경우가 존재합니다.
- offsetTop, offsetLeft, offsetWidth, offsetHeight
- scrollTop, clientTop
- getcomputedStyle(), currentStyle ( IE 에서만 )
즉, DOM
이 느린 것이 아니라, DOM Manipulation
할 때 발생하는
rendering calculation
이 느린 것 입니다.
V-DOM
은, DOM Manipulation의 횟수를 최소화하여 실제 DOM
의 조작을 줄이는 것입니다.
자, 그럼 간단한 VDOM 예제를 볼까요?
아래와 같은 HTML Tag가 있습니다.
<ul class="list">
<li>item1</li>
<li>item2</li>
</ul>
이 TAG를 JSON으로 치환하면,
{ type: 'ul', props: { 'class': 'list' }, children: [
{ type: 'li', props: {}, children: ['item1'] },
{ type: 'li', props: {}, children: ['item2'] },
]}
이런 식으로 표현될 수 있겠죠?
이것을 다시 javascript Function 으로 사용할 수 있게 표현하면
function h(type, props, ...children) {
return { type, props, children };
}
이렇게 되고,
JSON을 javascript단에서 이런 식으로 표현할 수 있습니다.
const tg = (
h('ul', { prop: 'list' },
h('li', {}, 'item1'),
h('li', {}, 'item2'),
);
);
이렇게 해서, DOM Element를 생성한 후에, append 하면 됩니다.
function createElement(node) {
if (typeof node === 'string') {
return document.createTextNode(node);
}
const $elm = document.createElement(node.type);
node.children.map(createElement).forEach($elm.appendChild.bind($elm));
return $elm;
}
const tg = (
h('ul', { prop: 'list' },
h('li', {}, 'item1'),
h('li', {}, 'item2'),
);
);
const $rootelm = document.getElementById('root');
$rootelm.appendChild(createElement(tg));
위 처럼 function으로 사용하는 경우도, React처럼 JSX 포맷에 맞추어 사용하는 경우도 있습니다.
하지만, 미리 계산
해 놓는다는 특징 때문에, 정말로 신경써서 사용하지 않으면 메모리 이슈가 있을 수 있습니다.
VDOM
이 항상 기존의 DOM
과 비교하여 빠른 것은 아닙니다.
Comments