什么是diff算法
根据B站中,以及查阅资料了解到的vue中的 diff算法
思路还有想法,记录一次,因为没有对于写博客相关而言是纯新手,所以求大家轻喷
什么虚拟DOM
- 虚拟DOM是表示真是DOM的JS对象
css
// 结构为
let Vbode = {
tagName:'div'
props:{
'class':'container',
}
children:[
{
tagName:'p',
props:{
"class":'item'
},
text:'文字内容'
},
{
tagName:'strong',
props:{
"class":'item'
},
text:'文字内容'
}
]
}
// 解释
tagName 标签名
props 标签属性
text 文本属性
children 子属性
diff算法用来干嘛
一段真实的DOM数据 , 对应一段虚拟的DOM对象 , 如果我们修改了 真实DOM 那么就会产生一段新的虚拟DOM对象,新旧两个虚拟对象是存在差异的,如果能快速找到差异,就能最小化的去更新视图
在vue内部专门准备了一套算法来进行新久值比对 ,这个比较方法就是diff算法 ,它的作用就是赵处差异,最小化更新视图
虚拟DOM的JS对象如何进行差异处比较
如何进行子元素内容比较
- oldvnode 有children属性
- newvnode 有childrend 属性
- 按照同级进行比对
- 同级比对的方法 采用的是 首尾指针法
vue2中的首尾指针法
自底向上、深度优先
比对不同的版本
-
不管新旧的虚拟DOM节点都是有 首节点 start 和尾节点 end
- 首先 oldS首节点 会去跟 newS 首节点去比对,
- 如果没有比对成功 ,旧虚拟节点(oldS首节点 ),会去和新虚拟节点(newE尾节点) ,
- 如果依旧没有比对成功 ,旧虚拟DOM(oldE尾节点 ) 会去跟 新虚拟DOM(newS首节点)去做比对
- 如果依旧没有比对成功,旧虚拟DOM(oldE尾节点 ) 会去跟新虚拟DOM(newE尾节点)去做比对
- 依次比较 ,当比较成功后退出当前比较
- 渲染结果以 newVnode 为准
- 每次比较成功后 start 点 和end点 向中间靠拢
- 当新旧节点中 有个start点 跑到end点右侧时终止比较
- 如果都匹配不到(首尾指针法 ),则旧虚拟DOM key值 去比较 新虚拟DOM 的key值 ,如果key相同则复用 ,并移动到新虚拟DOM 的位置
比对有相同的内容
- 首先 oldS 和newS做比对,没有比对成功
- 接着 oldS 和 newE 做比对,比对成功,更新真实DOM ,将比对成功的结果按照 newVnode 节点中展示的内容,移动节点
- 因为上一次比对成功,oldVnode 比对成功,oldVnode 的 开始节点 往左侧移动,然后再去跟 newVnode 的start 节点去做比对,如果比对成功,那么真实DOM 就会根据 newVnode的节点位置 进行更新
- 因为上一次 oldStart 和 newStart 比对成功,所以两者都会向左移动一下,接着开始第三次比对,oldStart 和newStart 比对成功,因为newVnode 中的 被比对的内容位置是第二位,所以真实DOM中的内容位置也需要调整
- 接着,oldVnode 和 newVnode 的 start节点 位置在向左侧移动,因为oldVnode 的 内容长度小于 newVnode 的长度,所以此时新旧虚拟DOM 内容比对结束,此时会将newVnode 中没有被比对的内容按照坐标放在真实DOM中
- 没有新旧虚拟节点比对结束后,newVnode中的长度小于oldVnode的长度,则需要将真实DOM中的newVnode没有的内容进行删除
vue2、vue3的diff算法有什么区别
- Vue3 中,引入一种称为 静态标记的dff算法 。在编译阶段,Vue会对模板进行静态分析 ,并给静态节点添加一个标记 。在更新过程中,Vue会跳过这些静态节点的比较 ,只对非静态节点进行diff操作,这个优化可以大大减少diff算法的时间复杂度,提高更新性能
- Vue2中,vue实用了一种称为双指针算法的diff策略。当进行更新操作时,Vue会逐层比较新旧虚拟DOM树,通过比较虚拟DOM节点的标签名,key 等属性来判断节点是否相同,以此决定是否需要更新该节点以及其子节点。这个算法的时间复杂度时 O(n) , 其中n时节点数量
Vue3中组件级别的diff策略
这个是vue3的优化的内容
在Vue2中,每次内容更新 都会对整个组件进行diff操作 ,无论组件内部是否有变化,这么操作是非常损耗性能的。
而在 vue3中, Vue会跟踪每个组件的依赖,只对发生变化的组件进行 diff操作,从而进一步提供性能
在此优化下大规模应用、复杂组件等等的场景下表现更好