news 2026/8/22 1:32:35

【vue】diff算法简介

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【vue】diff算法简介

一、先搞懂:最长递增子序列(LIS)是什么?

最长递增子序列(Longest Increasing Subsequence,简称 LIS)是动态规划/贪心+二分领域的经典算法问题,核心是找一个数组中「元素严格/非严格递增、且不要求连续」的最长子序列。

1. 核心概念(通俗举例)
  • 子序列:数组中挑出部分元素(顺序不变,可间隔),比如[10,9,2,5,3,7,101,18]的子序列可以是[2,5,7,101]
  • 递增:子序列中后一个元素 > 前一个(严格递增,也可定义为 ≥ 非严格);
  • LIS:满足递增的最长子序列,比如上面数组的 LIS 长度是 4([2,3,7,101][2,5,7,101])。
2. 两种核心解法(重点讲 Vue3 用的高效版)
解法时间复杂度核心思路
动态规划(DP)O(n²)dp[i]表示以第 i 个元素结尾的 LIS 长度,遍历每个元素对比前面所有元素更新 dp
贪心+二分O(n log n)维护一个“最小末尾数组”,用二分找替换位置,数组长度就是 LIS 长度(Vue3 用这个)
贪心+二分 通俗示例(比如数组[2,5,3,7,11,8,10,13,6]
  1. 初始化空数组tails = []
  2. 遍历每个元素:
    • 2:tails 空,直接加 →[2]
    • 5:比 tails 最后一个大,加 →[2,5]
    • 3:比 5 小,找 tails 中第一个 ≥3 的位置(索引1),替换 5 →[2,3]
    • 7:比 3 大,加 →[2,3,7]
    • 11:加 →[2,3,7,11]
    • 8:替换 11 →[2,3,7,8]
    • 10:替换 8 →[2,3,7,10]
    • 13:加 →[2,3,7,10,13]
    • 6:替换 7 →[2,3,6,10,13]
  3. 最终 tails 长度 5,就是 LIS 长度(注意 tails 不是真正的 LIS,只是长度相等)。

二、Vue3 中是否用到 LIS?—— 不仅用了,还很关键!

Vue3 在虚拟 DOM 的 diff 算法中,核心使用了 LIS 算法优化「列表更新时的 DOM 移动逻辑」,是提升 diff 性能的关键。

1. 为什么需要 LIS?(背景)

当 Vue 渲染列表(比如v-for)且节点有key时,更新列表(比如增删、排序)需要对比「老 vnode 数组」和「新 vnode 数组」,核心目标是:最小化 DOM 操作(少移动、少删除/新增)

比如老列表:[a, b, c, d](key 对应),新列表:[b, d, a, c]。如果直接暴力更新,会大量移动 DOM;但如果找到「不需要移动的最长节点序列」,只移动其他节点,就能大幅减少操作。

2. Vue3 中 LIS 的具体应用流程

Vue3 的patchChildren方法(处理子节点更新)中,针对「新老节点都是数组且有 key」的场景,核心步骤:

步骤1:建立映射,筛选“可复用节点”
  • 遍历新节点数组,记录「key → 新节点索引」的映射;
  • 遍历老节点数组,找到“新数组中也存在的节点”,生成一个source数组:source[i] = 新数组中该老节点的索引(不存在则为 -1)。

举例:

  • 老节点:[a(key:a), b(key:b), c(key:c), d(key:d)]
  • 新节点:[b(key:b), d(key:d), a(key:a), c(key:c)]
  • source 数组:[2, 0, 3, 1](a 在新数组索引 2,b 在 0,c 在 3,d 在 1)。
步骤2:计算 source 数组的 LIS(关键!)

上面的 source 数组[2,0,3,1],其严格递增的 LIS[0,1](对应老节点 b、d)或[2,3](对应 a、c)—— 这个 LIS 对应的老节点,就是「不需要移动的最长序列」。

步骤3:基于 LIS 最小化 DOM 移动

Vue3 会从后往前遍历新节点,结合 LIS 结果:

  • LIS 中的节点:位置已经“天然有序”,无需移动;
  • 非 LIS 中的节点:只需要移动到目标位置,而非删除重建。
3. 为什么用 LIS?

因为 LIS 是「最长的无需移动序列」,能最大程度减少 DOM 操作次数(DOM 移动是高性能开销操作),把 diff 算法的时间复杂度从 O(n²) 优化到 O(n log n),这也是 Vue3 diff 比 Vue2 更高效的核心原因之一。

4. Vue3 中 LIS 的源码位置

核心代码在runtime-core/src/patchChildren.ts中的getSequence函数(就是贪心+二分实现的 LIS),简化版核心逻辑如下:

// Vue3 源码中 getSequence 函数(简化版)functiongetSequence(arr){constlen=arr.length;constresult=[0];// 存储 LIS 的索引(不是值)constp=newArray(len).fill(0);// 记录前驱节点,用于还原完整 LISletlastIndex;letstart,end,mid;for(leti=0;i<len;i++){constval=arr[i];lastIndex=result[result.length-1];if(val>arr[lastIndex]){p[i]=lastIndex;result.push(i);continue;}// 二分找替换位置start=0;end=result.length-1;while(start<end){mid=(start+end)>>1;if(arr[result[mid]]<val){start=mid+1;}else{end=mid;}}if(val<arr[result[start]]){if(start>0){p[i]=result[start-1];}result[start]=i;}}// 还原完整的 LIS 索引leti=result.length;letlast=result[i-1];while(i--){result[i]=last;last=p[last];}returnresult;}

三、总结

  1. 最长递增子序列(LIS)是找数组中「最长递增非连续子序列」的算法,Vue3 用的是 O(n log n) 的贪心+二分实现;
  2. Vue3 在列表 diff 算法中核心依赖 LIS:通过计算可复用节点索引数组的 LIS,找到“无需移动的最长节点序列”,最小化 DOM 操作,提升更新性能;
  3. 这是 Vue3 对比 Vue2 diff 算法的重要优化点(Vue2 未用 LIS,diff 时间复杂度更高)。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/21 2:11:25

磷酸铁锂,零下就让车主破防了,长江以北都不适合!

业界都清楚电车怕冷&#xff0c;但是车主没想到这么怕冷&#xff0c;磷酸铁锂电池在零下的温度续航就已低至六成左右了&#xff0c;如果再开空调啥的&#xff0c;那就只有四成续航了&#xff0c;这样的续航让长江以北的车主在这个冬天彻底破防了。某车主用的插混&#xff0c;电…

作者头像 李华
网站建设 2026/8/21 2:21:38

Qwen-Image-Edit-2509镜像发布:基于自然语言指令的智能图像编辑新突破

Qwen-Image-Edit-2509镜像发布&#xff1a;基于自然语言指令的智能图像编辑新突破 在电商大促期间&#xff0c;一个运营团队需要在几小时内更新上千张商品图的价格标签、促销文案甚至主视觉风格。传统流程中&#xff0c;这依赖设计师手动操作Photoshop&#xff0c;效率低、成本…

作者头像 李华
网站建设 2026/8/21 23:00:09

人类智能和机器智能之间存在不少非科学逻辑

“人类智能和机器智能共生共融的非科学逻辑”并非指它们的关系毫无规律&#xff0c;而是强调&#xff1a;真正决定二者能否“共生共融”的&#xff0c;并不只是算法、算力、数据这些“科学层”因素&#xff0c;更取决于一系列无法被完全形式化、却又真实左右融合进程的“非科学…

作者头像 李华
网站建设 2026/8/22 0:52:40

Navicat重置工具终极指南:5分钟搞定Mac试用期解决方案

Navicat重置工具终极指南&#xff1a;5分钟搞定Mac试用期解决方案 【免费下载链接】navicat_reset_mac navicat16 mac版无限重置试用期脚本 项目地址: https://gitcode.com/gh_mirrors/na/navicat_reset_mac 还在为Navicat Premium的14天试用期结束而焦虑吗&#xff1f;…

作者头像 李华
网站建设 2026/8/21 5:49:04

Seed-Coder-8B-Base是否支持中文变量命名?实测告诉你答案

Seed-Coder-8B-Base是否支持中文变量命名&#xff1f;实测告诉你答案 在如今AI编程助手遍地开花的时代&#xff0c;开发者早已不再满足于“能不能写代码”&#xff0c;而是更关心&#xff1a;“它懂我吗&#xff1f;”——尤其是当我们想用“用户数量”代替user_count、用“计算…

作者头像 李华
网站建设 2026/8/21 17:56:51

Dify部署实战|基于Qwen-Image构建企业级AIGC创作平台

Dify部署实战&#xff5c;基于Qwen-Image构建企业级AIGC创作平台 在广告公司的一次头脑风暴中&#xff0c;设计师们正为某快消品牌的新品海报反复修改——客户要求更换三次文案、调整两次配色&#xff0c;每次改动都意味着重新渲染整张图。这种高频微调的“返工地狱”&#xf…

作者头像 李华