本文已参与[新人创作礼]活动,一起开启掘金创作之路
这里只是简单描述,如需详细了解请去往下方链接
一.虚拟DOM(Virtual DOM)
1.什么是虚拟DOM
是一个用来描述真实DOM的JavaScript对象
(1)真实DOM
<div>
<span>a</span>
</div>
(2)对应的虚拟DOM
let vnode = h('div', [
h('span','a')
])
注:h函数为render函数渲染
2.为什么要使用虚拟DOM
MVVM框架解决视图和状态同步问题
模板引擎可以简化试图操作,没办法跟踪状态
虚拟DOM跟踪状态变化
virtual-dom的动机描述
(1)虚拟DOM可以维护程序的状态,跟踪上一次的状态
(2)通过比较前后两次状态差异更新真实DOM
跨平台使用
(1)浏览器平台渲染DOM
(2)服务端渲染SSR( Nuxt.js/Next.js ),前端是Vue向,后者是react向
(3)原生应用(Weex/React Native)
(4)小程序(mpvue/uni-app)
真实DOM的属性很多,创建DOM节点开销大
虚拟DOM只是普通的JavaScript对象,描述属性不多,创建开销小
复杂视图情况下提升渲染性能(操作DOM性能消耗大,减少操作DOM的范围可节省性能)
3.使用虚拟DOM就一定比直接渲染真实DOM快吗?
不是的,为什么?
(1)慢
将DOM1替换为DOM2
无论是操作真实DOM还是虚拟DOM都是创建一个DOM2替换掉DOM1,同样的结果,结果操作虚
拟DOM还要去创建虚拟DOM+DIFF算法对比,就显得很麻烦
(2)快
当DOM树里的某个子节点的内容变更
一个父节点里面有多个子节点,当有一部分子节点内容发生变化时,我们就没必要重新渲染DOM树,
这时候虚拟DOM+DIFF算法去找到改变的子节点去更新它的内容即可,可在复杂视图情况下提升渲
染性能,减少DOM的操作(重绘重排)
4.虚拟DOM库
Snabbdom
Vue2内部使用的虚拟DOM就是改造的Snabbdom
大约200SLOC
通过模块可扩展
源码使用TypeScript开发
最快的Virtual DOM之一
virtual-dom
二.DIFF算法
1.简述
DIFF算法其实就是找出新旧两者之间的差异;
DIFF 算法首先要明确一个概念就是DIFF的对象是虚拟DOM(virtual dom),更新真实DOM是DIFF
算法的结果。
2.传统DIFF算法
传统算法查找两颗树每一个节点的差异会运行n1(dom1的节点数)的n2(dom2的节点数)次方去对比,找到差
异的部分再去更新
3.snabbdom的DIFF算法优化
Snbbdom根据DOM的特点对传统的diff算法做了优化,DOM操作时候很少会跨级别操作节点,只比较同级
别的节点
4.snabbdom
init()设置模块,创建patch()函数
使用h()函数创建JavaScript对象(Vnode)描述真实DOM
patch()比较新旧两个Vnode
把变化的内容更新到真实DOM树
5.v-for中的key的作用
(1)DIFF操作可以更加快速,准确(避免渲染错误)
(2)不推荐使用索引作为key(Vue2)
key
使用key来给每个节点做一个唯一标识,DIFF算法就可以正确的识别此节点,找到正确的位置区插入新的节点
index
1)可变列表用index当key容易出bug,非可变列表用index当key可以提升性能,index作为key,只适用于不依赖子组件状态或临时 DOM 状态 (例如:表单输入值) 的列表渲染输出。
2)应将与元素唯一对应的非索引值作为key,可以最大化利用dom节点,提升性能