소개
Vue.js는 빠른 로딩 속도와 쉬운 확장성으로 알려진 자바스크립트 프레임워크입니다. 필요에 따라 가상 돔을 사용하여 실제 돔을 업데이트하는 기능 중 일부를 직접 연결할 수 있습니다.
가상 돔을 이해하는 것이 Vue.js를 학습하는 데 필요한 요구 사항은 아니지만, 신규 Vue 개발자가 뒤에서 일어나는 것들에 대해 이해하는데 도움이 될 수 있습니다.
DOM이란
<!DOCTYPE html>
<html>
<head>
<title>Page Title</title>
</head>
<body>
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
</body>
</html>
우리가 Vue.js의 가상 돔에 대해 이야기 하기 전에 돔이 무엇인지에 대해 이해하는 것이 중요합니다. DOM(Documents Object Model)은 모든 마크업 언어(사용자의 HTML)를 연결된 노드로 처리하는 인터페이스의 일종입니다. 나무와 같은 구조로 저장된 마크업 요소에 대한 객체의 인터페이스로 볼 수 있습니다.
DOM을 사용하면 요소에 대한 스타일을 쓰고 변경할 수 있으며 요소 자체도 변경할 수 있습니다. 이렇게 하려면 요소 태그 또는 CSS 스타일이 노드 및 개체로 표시되므로 문서의 헤드와 본문에 추가, 수정 또는 삭제해야합니다.
전통적인 DOM이 왜 충분하지 않은가요?
DOM을 사용하면 좋습니다. 하지만 애플리케이션이 증가함에 따라(이동할 노드 수, 요소의 수 및 요소와 통신하는 스크립트 수) DOM은 속도가 느려지고 처리 능력이 크게 소모됩니다. DOM을 검색하거나 업데이트하려고 하면 애플리케이션 성능에 영향을 미치게 됩니다. 이러한 것이 가상 DOM이 생긴 이유입니다.
React에 의해 대중화된 이 가상 DOM 기반의 렌더링에는 중요한 특징이 하나 있는데, 바로 View 갱신을 처리할 때는 매번 전체 화면을 처음 부터 다시 렌더링합니다. 데이터 혹은 여러 요인에 따라 View가 변경되어야 하는 경우, 변경될 부분을 구분해서 그 부분만 다시 렌더링 하도록 로직을 구성하는 것이 아니라 매번 전체 화면을 처음부터 다시 생성하듯이 렌더링을 한다는 것입니다.
전체를 재렌더링하는 것은 비효율적이라고 말했는데 어떻게 된걸까요? 만약 실제 브라우저의 DOM을 이런식으로 매번 전체를 다시 그리도록 하는 것은 성능이 너무 떨어지겠지만, 가상 DOM을 매번 처음부터 다시 렌더링합니다. 가상 DOM은 단순히 메모리 요소이기 때문에 생성하고 업데이트하는 것이 매우 빠릅니다.
이렇게 로직에서 가상 DOM을 만들어 내면 프레임워크는 가상 DOM을 브라우저에 반영하는 과정에서 변경사항만을 효율적으로 구분(Diff 알고리즘)해서 최소한의 변경만이 이루어 지도록하는 것입니다.
Vue.js의 가상 DOM
가상 DOM을 기반으로 하는 React와 Vue.js는 컴포넌트 단위로 애플리케이션을 구성하는데, 각각의 컴포넌트는 render 함수를 가지고 있고 render 함수로 그 컴포넌트의 view를 가상 DOM의 Node로 생성하게 됩니다.(vue.js의 경우 vnode) 그러면 프레임워크에서 생성된 가상 DOM Node Tree를 기반으로 실제 브라우저 DOM Tree를 생성 및 업데이트합니다.
이러한 가상 DOM은 실제 DOM과 Vue 인스턴스 사이에 위치합니다.
new Vue({
el: '#app',
data: {
text: 'hi LogRocket'
},
render(createElement) {
return createElement(
'h1',
{ attrs: { id: 'headers' } },
this.text
);
}
});
위의 코드를 렌더링 시 아래 요소가 반환됩니다.
<div id=’app’>
<h1 id=’headers’>hi LogRocket</h1>
</div>
React vs Vue.js V-DOM
React와 Vue.js와의 차이점은 React는 render 함수를 직접 구현하도록 되어 있지만, Vue.js는 template를 작성하면 컴파일러가 이를 render 함수로 생성해줍니다. 내부 실제 구현은 react와 유사하지만 코드 레벨에서는 template와 코드를 분리하여 작성할 수 있는 차이가 존재합니다.
Vue.js는 react처럼 render 함수를 직접 코드로 작성하는 것도 지원합니다.
//template를 이용하는 경우
Vue.component( 'my-comp', {
name : 'my-comp',
template : `
<div>
<h1>My Component</h1>
</div>
`
});
//JSX를 사용하는 경우
Vue.component( 'my-comp', {
name : 'my-comp',
render : function( h ) {
return (
<div>
<h1>My Component</h1>
</div>
);
}
});
//render 함수를 직접 작성하는 경우
Vue.component( 'my-comp', {
name : 'my-comp',
render : function( createElement ) {
return createElement( 'div', [
createElement( 'h1', 'My Component' )
]);
}
});
어떻게 동작하는가?
— 1단계 컴파일은 템플릿을 렌더링 함수로 컴파일하는 단계입니다.
— 2단계 DOM에서 종료되는 가상 DOM 노드를 생성하는 렌더 기능 실행 브라우저에 표시됩니다.
첫 번째 단계는 한 번만 수행되며, 상당한 성능 향상을 위해 서버에서 수행할 수 있습니다. 프로토타이핑의 경우 클라이언트에서 컴파일도 수행할 수 있지만 Vue.js 런타임 컴파일러를 포함해야 합니다.
두 번째 단계는 구성 요소 마운트 수명 주기 동안 클라이언트에서 한 번 수행되며, 매번 서로 다른 알고리즘이 템플릿을 다시 렌더링해야 한다고 결정합니다.
Reference
https://blog.logrocket.com/how-the-virtual-dom-works-in-vue-js/
https://m.blog.naver.com/PostView.nhn?isHttpsRedirect=true&blogId=jjoommnn&logNo=221082930638
'Vue 스터디' 카테고리의 다른 글
[Vue.js] vue-i18n (0) | 2021.07.28 |
---|---|
React vs Vue.js 문법적 차이 (0) | 2021.07.19 |
Vue.js 에서 HOC(High Order Component) 만들기 (0) | 2021.07.15 |
Vue.js 라우터 네비게이션 가드 (0) | 2021.07.15 |
Nuxt.js에서 Axios 통신 (0) | 2021.06.24 |