vue-了解diff算法

122 阅读2分钟

思路: 1)diff算法干什么;2)必要性,为什么;3)何时执行;4)具体的执行方式;5)vue3中的优化

  • 1.Vue中的diff算法称为patching算法,它由Snabbdom修改⽽来,虚拟DOM要想转化为真实DOM就需要通过 patch⽅法转换。

  • 2.最初Vue1.x视图中每个依赖均有更新函数对应,可以做到精准更新,因此并不需要虚拟DOM和patching算法⽀ 持,但是这样粒度过细导致Vue1.x⽆法承载较⼤应⽤;Vue 2.x中为了降低Watcher粒度,每个组件只有⼀个 Watcher与之对应,此时就需要引⼊patching算法才能精确找到发⽣变化的地⽅并⾼效更新。

  • 3.vue中diff执⾏的时刻是组件内响应式数据变更触发实例执⾏其更新函数时,更新函数会再次执⾏render函数获 得最新的虚拟DOM,然后执⾏patch函数,并传⼊新旧两次虚拟DOM,通过⽐对两者找到变化的地⽅,最后将其 转化为对应的DOM操作。

  • 4.patch过程是⼀个递归过程,遵循深度优先、同层⽐较的策略;以vue3的patch为例: ⾸先判断两个节点是否为相同同类节点,不同则删除重新创建 如果双⽅都是⽂本则更新⽂本内容 如果双⽅都是元素节点则递归更新⼦元素,同时更新元素属性 更新⼦节点时⼜分了⼏种情况: 新的⼦节点是⽂本,⽼的⼦节点是数组则清空,并设置⽂本; 新的⼦节点是⽂本,⽼的⼦节点是⽂本则直接更新⽂本; 新的⼦节点是数组,⽼的⼦节点是⽂本则清空⽂本,并创建新⼦节点数组中的⼦元素; 新的⼦节点是数组,⽼的⼦节点也是数组,那么⽐较两组⼦节点,更新细节blabla

    1. vue3中引⼊的更新策略:编译期优化patchFlags、block等,打标记,指明具体更新的内容。

vue底层的vdom是数组n1,n2存储,react是fiber对象组成的单链表

  • 掐头去尾:两头循环,保留n1,n2相同的,判断:n1为空,添加n2;n2为空,删除n1

  • 新节点做map(键不变,索引为值):react中是老节点做map

  • 建立新数组(n2剩余长度):值全为0

  • 遍历老节点:复用patch,找对应的新数组,存值为下标+1,否则删除move

  • 遍历新节点:从后往前,(好插入) ,数组值为0,直接插入,不为0,找到最长递增子序列,全部不动,继续遍历下一个

  • 最长递增子序列:二分查找,插入元素