虚拟 DOM 和 DOM diff
虚拟 DOM
虚拟 DOM 是什么
虚拟dom实际上就是使用js对象描述的dom树,本质上就是一个js对象。大概长这样
const vNode = {
tag: "div", // 标签名 or 组件名
data: {
class: "red", // 标签上的属性
on: {
click: () => {} // 事件
}
},
children: [ // 子元素
{ tag: "span", ... },
{ tag: "span", ... }
],
...
}
虚拟 DOM 有什么用?
由于虚拟dom是抽象出来的js对象,和操作真实dom相比中间经过了某些计算,使得在某些情况下可以优化dom操作。 1.减少dom操作次数 将多次操作合并一次操作,例如在页面中加入成百上千个元素,虚拟dom可以优化成一次操作 2.减少dom操作范围 凭借虚拟dom的diff算法,能减少操作范围,例如在一百个元素中更新十个元素,diff算法可以找出需要更新的元素,只更新这十个元素。
虚拟DOM有什么缺点?
创建虚拟DOM需要用特定函数,但可以简化成XML写法,如vue的单文件模板,但仍需依赖vue-loader转换。
DOM diff
DOM diff 是什么
是一种新旧虚拟DOM的对比算法
DIFF算法在执行时有三个维度,分别是Tree DIFF、Component DIFF和Element DIFF,执行时按顺序依次执行,它们的差异仅仅因为DIFF粒度不同、执行先后顺序不同。
Tree diff 将新旧两棵树逐层对比,找出哪些节点需要更新 如果节点是组件就看 Component diff 如果节点是标签就看 Element diff Component diff 如果节点是组件,就先看组件类型 类型不同直接替换(删除旧的) 类型相同则只更新属性然后深入组件做 Tree diff(递归) Element dif f如果节点是原生标签,则看标签名 标签名不同直接替换,相同则只更新属性 然后进入标签后代做 Tree diff(递归)
DOM diff 有什么用?
减少dom操作次数,优化dom操作范围,提升渲染效率
DOM diff 有什么缺点?
同级节点对比存在问题 比如一个列表,有多个子元素,如果删除其中给一个子元素,那么后续所有子元素都会前移一个位置,浪费性能。 因此,vue中使用v-for一般要同时绑定key,这代表每个元素都有了唯一标识,这样当删除某个元素时,就只会根据key直接更新该元素,不会影响其他元素。