前言
DOM全称 Document Object Model(文档对象模型),为HTML提供API,让开发者能通过这些API去操作HTML。
Virtual DOM(虚拟的文档对象模型),利用JavaScript做了一层中间层来模拟DOM节点,然后再通过特定的 render 方法将其渲染成真实的 DOM 节点。
为什么会出现Virtual DOM?简单来说就是直接操作DOM的代价比较大。
浏览器渲染
浏览器拿到HTML后需要解析,然后渲染,流程为:
- 解析HTML,构建DOM树;
- 解析CSS,构建CSSOM树;
- 合并DOM树和CSS规则,生成render树;
- 布局render树(Layout/reflow),负责各元素尺寸、位置的计算;
- 绘制render树(paint),绘制页面像素信息;
- 浏览器会将各层的信息发送给GPU,GPU将各层合成(composite),显示在屏幕上。
这里最耗性能的是第4和第5两步,而当开发者在对DOM进行操作的时候,很大概率会导致浏览器需要重新解析,也就是从头来一遍,具体内容这里先不讨论。
可以看一下一个 div 标签含有多少属性
var div = document.createElement('div');
var keys = [];
for (var key in div){
keys.push(key)
}
keys.length // 2412
3
4
5
6
一个基础的DOM元素就这么庞大,而 Virtual DOM 是用js去描述一个DOM节点,省去了很多不必要的属性或方法
VNode
VNode 也就是 Virtual Node 虚拟节点的意思
代码在:\src\core\vdom\vnode.js
export default class VNode {
tag: string | void; // 元素标签
data: VNodeData | void; // 数据
children: ?Array<VNode>; // 子节点
text: string | void; // 文本内容
elm: Node | void; // 对dom对象的持有
ns: string | void;
context: Component | void; // rendered in this component's scope
key: string | number | void;
componentOptions: VNodeComponentOptions | void;
componentInstance: Component | void; // component instance
parent: VNode | void; // component placeholder node
// ... 省略代码 ...
}2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
这里只看前几个其实就可以了,剩下的都是和Vue的特性相关。
只在本章节讲的话可以看出来 VNode 其实很简单,就是一些对DOM元素的映射,不需要操作DOM。
Virtual DOM
Virtual Dom 是通过 JS 层面的计算,返回一个 patch 对象,即补丁对象,在通过特定的操作解析 patch 对象,完成页面的重新渲染。
VNode的实现借鉴了 snabbdom 开源库。
Virtual Dom要映射到真实DOM的话,需要经历 create、diff、patch 等过程,在VueJs中,create 就是上一章说到的 createElement 方法,下一章来看一下createElement的相关代码。
可以参考的资料 https://juejin.im/post/5cac5a87e51d456e7618a67bhttps://segmentfault.com/a/1190000014070240