Vue.js : Virtual DOM.md

Vue.js 2.0에 새롭게 추가된 "Virtual DOM"에 대하여...

Vue.js 는 주로 Angular와 React의 장점들을 고루 갖고 있는 특징이 있다.

이번에 Vue.js 2.0 버전의 주요 특징 중 하나로 페이지 변경을 위한 "Virtual DOM" 이 추가되었다.

"Virtual DOM"은 React에서 많이 들어보았을 것이다.

React와 Ember에서 사용하는 이 "가상 돔"은 웹 페이지의 변경 속도를 매우 빠르게 해준다.

 

먼저 가상 돔의 원리를 이해하기 전에 브라우저의 동작 원리DOM에 대한 몇 가지 특징을 알아볼 필요가 있다.

 

 

브라우저의 동작

사용자가 웹 브라우저의 주소 표시줄(사용자 인터페이스)에 URL을 입력하면 브라우저 엔진은 이를 해석하고,

적절한 HTTP Request Message를 만들어 웹 서버에 전달하게 된다. 웹 서버는 요청된 방식에 따라 응답 메시지를 만들

어 클라이언트에게 다시 보내준다. 브라우저의 렌더링 엔진 은 웹 서버에서 응답한 메시지의 콘텐츠를 화면에 표시한다.

( 예를 들어 HTML을 요청하면 HTML과 CSS를 파싱하여 화면에 표시 )

 

렌더링 엔진의 기본적인 동작 과정 ( HTML만을 예시로 들자면 )
DOM 트리 구축을 위한 HTML 파싱 => 렌더 트리 구축 => 렌더 트리 배치 => 렌더 트리 그리기 -> 표시

( 보다 자세한 렌더링 과정은 "브라우저는 어떻게 동작하는가?" 문서를 보길 바란다 )

HTML 파싱 과정에서 DOM 트리가 생성되는데 "DOM" 이 무엇인지 알아보자

 

DOM(Document Object Model)

문서의 객체 모델

- HTML 내에 들어 있는 요소를 구조화 객체 모델로 표현 하는 양식

 

HTML 문서가 아래와 같다면

 

 

DOM 트리 구조는 아래처럼 표현할 수 있다. ( 이미지 출처 - http://d2.naver.com/helloworld/59361 )

 

domtree

 

 

DOM의 특징

  • 위의 그림과 같이 트리의 부모 자식 관계로 형성

  • HTML 요소들(nodes)을 탐색하고 수정할 수 있는 API를 제공

    ex) getElementById, removeChild

     

DOM의 문제점

= "It’s expensive to update the DOM"

 

우리는 스크립팅 언어인 자바스크립트를 사용하여 웹페이지를 동적으로 변경시킨다.

이 때, 브라우저는 목표 DOM 노드들을 찾은 후 원하는 변경 사항에 맞게 조작하기 위해 몇 가지 작업을 한다.

 

 

일반적인 앱에서, DOM에는 수 천개의 노드들이 존재할 수 있고 업데이트를 위해 복잡한 처리 과정이 필요하게 된다.

이로 인해 브라우저의 속도는 느려지게 된다. 상단의 브라우저 동작 원리를 설명한 이유는 이 문제점 속에 있다.

먼저 브라우저에서 페이지를 로드하게 되면 렌더링 트리와 돔 트리를 생성하게 되고 여러 과정을 거쳐서 브라우저에 CSS가 적용된 페이지가 그려지게 된다. 여기서 자바스크립트로 DOM을 조작할 때 렌더링 트리는 각 변경 사항마다 하나씩 해석하여 렌더링을 시키게 되는 구조이다.

그런데 만약 한 번의 상태 변경으로 여러곳의 DOM 변경(노드들의 수정)이 일어난다면 어떻게 될까?

수 천개의 노드들이 변경되어 렌더링 되기까지 적지 않은 시간이 걸릴 것이다.

현재까지 웹에서는 DOM 변경에 맞추어 렌더링도 여러번 하게 되는 구조일 수 밖에 없었다. 그리고 사실 pure JavaScript를 사용해 DOM 객체를 조작하는 비용보다 DOM을 조작했을 때 화면을 다시 그리는 비용(렌더링 계산)이 훨씬 크다.

(https://www.slideshare.net/gyeongseokseo/virtual-dom 참고)

 

이를 해결하기 위해 등장한 것이 "Virtual DOM" 가상 돔이다.

 

가상 돔 (Virtual DOM)

  • 먼저 가상 돔은 리액트에서 나온 개념이 아니다. 하지만 리액트는 무료로 이 개념을 사용하고 사용자들에게 제공한다. Vue.js도 마찬가지이다.

  • 가상 돔은 HTML 돔의 추상화 개념이다. 이것은 가볍고, 브라우저 스펙의 구현체와는 분리되어있다. 사실, 돔은 이미 추상화 개념이기 때문에 가상 돔은 추상화를 또 추상화한 개념이다.

  • DOM의 복사본을 메모리 내에 저장하여 사용

  • 변경 사항을 "가상의" 위치에서 처리하고, "실제 DOM"의 조작을 최소화한다. 즉, DOM트리를 모방한 가벼운 자바스크립트 객체를 통해 직접 DOM을 핸들링 하지 않고 퍼포먼스를 향상시킨다.

     

DOM 노드들은 일반적으로 HTML 문서에서 아래와 같이 표현된다.

 

아마도 아래 코드는 우리가 DOM API를 사용하여 DOM을 변경하는 방법일 것이다.

 

 

가상 DOM 노드들은 이처럼 자바스크립트 객체 형식으로 표현될 수 있다.

 

아마도 아래 코드는 우리가 가상 DOM을 변경하는 방법일 것이다.

 

 

DOM 조작을 위해서 getElementById와 같은 DOM API를 사용한 코드가 아닌 가상 돔을 사용한다면,
코드는 단지 자바스크립트 객체로 변경되는 매우 저렴한 비용이 들 것이다.

 

그런 다음, 아래 코드를 통해 가상 돔 변경 부분과 실제 돔의 동기화 작업이 이루어진다.

 

 

이런 방법으로 한 번의 상태 변경으로 여러곳의 DOM이 변경된다고 해도 가상화된 DOM에서 전부 변경하고
진짜 돔과 비교해서 변경된 부분을 한번에 적용시키는 방식으로 DOM의 렌더링 횟수를 줄이게 된다.

 

Vue.js version 2에서 추가된 가상 돔은 과연 괜찮을까?

 

1. 크기

가상 돔의 추가와 같은 여러 기능을 추가하기 위해서는 코드 패키지에서 많은 수의 라인을 추가하는 것을 의미한다.

그렇지만 Vue.js 2.0은 여전히 작은 파일 크기를 유지한다. (현재 릴리즈는 21.4kb)

2. 메모리

가상 돔의 유지를 위해서는 메모리 내에 DOM의 복사본을 생성한다.

돔의 변경 속도와 메모리 사용을 교환한 것이다.

3. 사용 환경

가상 돔은 많은 수의 변경 사항을 한꺼번에 처리할 때 사용하는 것을 추천한다.

하지만 단일 변경 사항이 드물게 일어난다면? 가상 돔은 돔 변경을 하기위해 무의미한 연산을 할 것이다.

 

그러므로, 만약 프로젝트가 상대적으로 적은 노드 수가 있다면 오히려 가상 돔으로 인해 페이지의 변경 속도가 느려질 것이다.

하지만 대부분의 단일 페이지 애플리케이션에서는 향상된 성능을 가질 것이다.

 


 

Vue.js의 가상 돔의 코드를 확인하고 싶다면 https://github.com/vuejs/vue/tree/dev/src/core/vdom 확인

 


 

Vue.js를 공부하다 나온 "가상 돔"을 이해하기 쉽게 설명드리고 싶었지만 어쩌다보니 구글링한 문서들의 내용들이 짬뽕이 되었습니다.. 아직 확실하게 이해못한 가상돔 개념과 처음으로 시도한 블로그 포스팅이 만나, 매우 부족한 글을 쓰게된 것 같습니다. 너그러운 마음으로 글을 봐주시길 바랍니다! Vue.js를 공부하면서 확실한 개념을 잡아갈 때마다 글을 다시 수정하도록 하겠습니다. 감사합니다.

 


 

참고 링크들

'Vue.js' 카테고리의 다른 글

MVVM(Model-View-ViewModel) in Vue.js  (0) 2018.01.19

+ Recent posts