Vue3 diff算法

vue2 diff

Vue2的diff算法执行updatevnode比较新旧节点时会优先处理特殊场景,即头头比对,头尾比对,尾头比对等,并借助key值找到可复用的节点进行相关操作,有效减少移动节点的次数。

vue3 diff

Vue3中移动节点时会先执行函数运用了动态规划的思想生成最长增长子序列的下标。
观察源码:

function getSequence(arr) {
  const p = arr.slice()                 //  拷贝原始数据并保存
  const result = [0]                    //  存储最长增长子序列的索引数组
  let i, j, u, v, c
  const len = arr.length
  for (i = 0; i < len; i++) {
    const arrI = arr[i]
    if (arrI !== 0) {
      j = result[result.length - 1]     //  j是子序列索引最后一项
      if (arr[j] < arrI) {              //  如果arr[i] > arr[j], 当前值比最后一项还大,可以直接push到索引数组(result)中去
        p[i] = j                        //  p记录第i个位置的索引变为j
        result.push(i)
        continue
      }
      u = 0                             //  数组的第一项
      v = result.length - 1             //  数组的最后一项
      while (u < v) {                   //  如果arrI <= arr[j] 通过二分查找,将i插入到result对应位置;u和v相等时循环停止
        c = ((u + v) / 2) | 0           //  二分查找 
        if (arr[result[c]] < arrI) {
          u = c + 1                     //  移动u
        } else {
          v = c                         //  中间的位置大于等于i,v=c
        }
      }
      if (arrI < arr[result[u]]) {
        if (u > 0) {
          p[i] = result[u - 1]          //  记录修改的索引
        }
        result[u] = i                   //  更新索引数组(result)
      }
    }
  }
  u = result.length
  v = result[u - 1]
  //把u值赋给result  
  while (u-- > 0) {                     //  最后通过p数组对result数组进行进行修订,取得正确的索引
    result[u] = v
    v = p[v];                        
  }
  return result
}

如数组[11,3,5,9,7],执行函数返回的结果为[1,2,4]

找到了此数组最长增长子序列对应的下标值,就能找出新旧节点中不需要移动的节点,直接原地复用,接下来只要操作其他节点就好了。
相较与vue2,更能有效复用dom,减少dom操作次数,提升了替换的效率。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值