Virtural DOM (VDOM)은 UI의 이상적인 또는 가상적인 표현을 메모리에 저장하고 ReactDOM과 같은 라이브러리에 의해 실제 DOM과 동기화하는 프로그래밍 개념이고 이러한 과정을 Reconciliation(재조정)이라고 한다.
Virtual DOM에 대해 학습하기 이전 브라우저에 Workflow를 간단히 확인해보자.
브라우저가 HTML을 전달받으면, 브라우저의 렌더 엔진이 이를 파싱하고 DOM 노드(Node)로 이뤄진 트리를 만든다. 각 노드는 각 HTML 엘리먼트들과 연관되어있다.
외부 CSS 파일과 각 엘리먼트의 inline 스타일을 파싱한다. 스타일 정보를 사용하여 DOM 트리에 따라 새로운 트리, 렌더 트리를 생성한다.
2-1. Render Tree 생성 - 그 뒤에선 무슨 일이 일어나는가?
Webkit에서는 노드의 스타일을 처리하는 과정을 ‘attachment’라고 부른다.
DOM트리의 모든 요소들은 ‘attach’라는 메소드가 존재하고 이 메소드는 스타일 정보를 계산해서 객체 형태로 반환한다.
이 과정은 (synchronous)작업이고, DOM 트리에 새로운 노드가 추가되면 그 노드의 attach 메소드가 실행된다. 렌더 트리를 만드는 과정에선, 각 요소들의 스타일이 계산되고 이 계산되는 과정에서 다른 요소들의 스타일 속성들을 참조하게 된다.
렌더 트리가 다 만들어지고 나면, 레이아웃 과정을 거치게 된다. 각 노드들은 스크린의 좌표가 주어지고, 정확히 어디에 나타나야할 지 위치가 주어진다.
마지막으로 렌더링 된 요소들에 색을 입히는 과정을 하게된다. 트리의 각 노드들을 거치면서 paint() 메소드를 호출한다. 그러고 나면 스크린에 원하는 정보가 나타나게 된다.
브라우저의 Workflow는 위 과정을 거치게 된다.
즉, DOM에 변화가 생기게 되면, Render Tree를 재생성하고(Render Tree가 재생성되면, 모든 요소들의 스타일이 다시 계산되게 된다.) 레이아웃을 만들고 페인팅하는 과정을 거치게 되는 과정을 반복하게 된다는 의미이다.
SPA(Single Page Application)에서는 DOM조작이 많이 발생하게 되는데, 이말의 의미는 DOM 조작에 맞게 그 변화를 적용하기 위해 브라우저가 많은 연산 과정을 거쳐야한다는 의미입니다.
즉, 전체적인 프로세스를 비효율적으로 만들게 된다는 의미이죠.
이러한 상황에서 Virtural DOM이 빛을 발하게 됩니다.
만약에 View에 변화가 있다면, 그 변화는 실제 DOM에 적용되기 전에 가상의 DOM에 먼저 적용하고, 그 최종적인 결과를 실제 DOM으로 전달하게 됩니다. 이로써 브라우저 내에서 발생하는 연산의 양을 줄이면서 성능이 개선됩니다.
Virtual DOM은 변화가 일어나면 그걸 오프라인 DOM 트리에 적용합니다. (이 오프라인 DOM 트리는 렌더링이 되는게 아니기 때문에 연산비용이 많이 들지 않는다.) 연산이 끝나고 나면 그 최종적인 변화를 실제 DOM에 던져준다. (DOM의 모든 변화를 묶어서 딱 1회만 진행한다.)
그렇게 되면 레이아웃 계산과 리렌더링의 규모는 커지겠지만, 모든 변화를 묶어서 진행하기 때문에 연산 횟수가 1회만 진행되게 되는 것이다.
Javascript는 명령형으로 작성했다.
예를 들면 아래와 같다.
해당하는 돔 요소 선택
const $element = document.querySelector('.element');
const $element2 = document.querySelector('.element2');
돔 요소의 이벤트 동작
$element.addEventListener('click', () => {});
클래스 네임 변경
$element.addEventListener('click', () => {
$element2.className = 'element3';
});
Angular.js, jQuery, backborn 등 이 존재했다.
앱의 규모가 커지고, 사용자 인터렉션이 많아지면서 데이터의 흐름을 파악하기 어려운 문제에 직면하게 된다.
이러한 문제점을 해결하기 위해 페이스북에서 데이터의 흐름 파악이 쉽게 데이터의 흐름을 한 방향으로만 흐르는 리액트 라이브러리를 만들어 오늘날까지 선풍적인 인기를 얻게 되었다.
참고 : https://velopert.com/3236, https://ko.reactjs.org/docs/faq-internals.html#what-is-the-virtual-dom, https://saiki.hashnode.dev/the-one-thing-that-no-one-properly-explains-about-react-why-virtual-dom