Virtual DOM
1、背景信息总结
- DOM 操作非常耗时耗性能(且现代前端框架要求不手动操作 DOM,可以大大提高开发效率)---- 因为会引起页面的回流或重绘
- JS 的执行很快(浏览器V8引擎的出现更加加快了JS的计算速度)
- 实现更好的跨平台(如浏览器端渲染、 Node.js 实现 SSR 服务端渲染、安卓/IOS、小程序等)
推出 ==> Virtual DOM(虚拟DOM)
将真实 DOM 抽象成一个以 JS 对象为节点的虚拟 DOM 树,DOM 的变化过程中不需要操作真实DOM,只需要操作 JS 对象(虚拟 DOM),再与真实 DOM比较差异,最后只对变化的 DOM 进行操作来更新真实 DOM,减少了 DOM 操作,大大提升了性能。
2、VDOM(Virtual DOM简写)是什么?
VDOM是个啥?:用 JS 对象模拟的 DOM 结构(树形结构)
一个用JS 对象表示 DOM 结构的简单例子:
<!-- DOM 结构 -->
<div id="cc" class="bigCc">
<p>DOM</p>
<ul style="font-size: 24px">
<li>huohuoit</li>
</ul>
</div>
<!-- JS 对象表示 -->
{
tag: 'div',
data: {
id: 'cc',
className: 'bigCc'
},
children: [
{
tag: 'p'
text: 'DOM'
},
{
tag: 'ul'
data: { style: 'font-size: 20px' }
children: [
{
tag: 'li',
text: 'huohuoit'
}
]
}
]
}
它的优势:
- 抽象了原本的渲染过程,实现了跨平台的能力
- diff 算法,减少 JS 操作真实 DOM 的带来的性能消耗
3、实现原理
用 JS对象 模拟 DOM 结构,然后比较出差异对象,再去操作 DOM
来看看整体的流程:
- 虚拟 DOM 发生变化时,比较两颗 DOM 树的差异,生成差异对象
- 根据差异对象更新真实 DOM
- 把虚拟 DOM 转换成真实 DOM 插入页面中
- 用 JS 对象模拟真实 DOM 结构
4、Vue 对 VDOM 的源码实现
1、描述
关注:使用 VNode 这个 Class 来描述 VDOM(VNode 由 Vue.js 的 _createElement 方法创建)
这里先关注一些主要描述点:
- elm:VNode 对应的真实 DOM 节点
- key:VNode 标记, diff 过程可以提高效率
- data:VNode 上的 class/attribute/style/绑定事件等数据
- children:VNode 的子节点
- text :文本属性
- tag:VNode 的标签属性
再看看 VNode 的创建过程:
- 初始化 Vue:new Vue( ),调用this._init方法
- Vue 实例挂载:通过$mount 方法挂载 DOM => 调用mountComponent 方法(实例化一个渲染 Watcher,并回调updateComponent 方法) => 调用mountComponent 方法(实例化一个渲染 Watcher,并回调updateComponent 方法)在updateComponent 方法中调用 vm._render 方法先生成VNode,最终调用 vm._update 更新 DOM
- 创建VNode:使用_render 方法(_render 方法把实例渲染成VNode,这里调用了_createE