Vuejs设计与实现6-Diff算法

六、Diff

基本原理

非 Diff 状态:更新时,卸载所有旧的 vnode 然后在挂载新的 vnode,无法复用,性能消耗大

Diff:新旧 vnode 进行比对,只更新有变化的地方

对于新旧 vnode,有以下三种更新方式:

  1. 新旧 vnode 的 children 长度一致:遍历一个,然后与另一个进行比对
  2. children 长度不一致,变量长度最短的那一个,然后依次挂载/卸载多出来的部分

DOM 复用

这里使用了 key 来让新旧 vnode 进行比对,提升复用度

移动节点的完整执行流程:

  1. 取出新 vnode 中的任意一个节点,获取其 key
  2. 寻找旧 vnode 中是否有相同的 key
  3. 如果有相同的 key,比对新旧 vnode 发现有改动,则打补丁 patch

节点移动解析

新旧 vnode 的 key 不一致,此时就需要把新 vnode 的引用移动到旧 vnode 对应的位置上(即使 key 值相同),才能让真实 DOM 渲染在同一个位置上

通过移动,使得新 vnode 可以应用到真实 DOM


七、双端 Diff

双端原理

新旧 vnode 的前后端均有一个 key,所以共计 4 个 keys

每轮进行一次交叉比较,单次命中后(即新旧节点的 key 相同),命中的索引向内收缩一个单位,之后进入下一轮交叉比较

交叉比较:

  1. oldvnode 头部节点与 newvnode 头部节点比较
  2. oldvnode 尾部节点与 newvnode 尾部节点比较
  3. oldvnode 头部节点与 newvnode 尾部节点比较
  4. oldvnode 尾部节点与 newvnode 头部节点比较

篇幅过大,无法阐述,后续补充


非理想情况

所谓非理想情况,即一轮交叉比较过程内,没有一次命中 key

解决方法:拿新 vnode 的一组子节点的头部节点去旧 vnode 对应子节点内找到可复用的节点


八、快速 Diff 算法

前后缀处理

首先进行预处理

  1. 将两段文本进行全等比较,如果相同,直接就不需要后续的 diff 了
  2. 删去两段文本相同的前后缀
  3. 设新旧子节点的头部节点为 j=0,让 j++,直到遇到不同的节点,在此过程中对于相同 key 值的新旧子节点都需要执行打补丁 patch(此过程处理所有前置节点)

索引过程

  1. 设置新子节点尾部为 newend,旧子节点尾部为 oldend
  2. newend 与 oldend 同时递减,处理所有的后置节点

注重原理分析,后续补充!


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Zhillery

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值