虚拟DOM
虚拟DOM(Virtual DOM)是Vue实现高效渲染的核心机制,是对真实DOM节点的抽象,用JS对象属性来描述真实DOM节点,虚拟DOM对象的节点属性与真实DOM属性一一对应,最终可以构建一颗真正的DOM树插入到文档中;在JS对象中,虚拟DOM表现为一个Object对象,并且最少包含标签名tag、属性attrs和子元素对象children三个属性。
虚拟 DOM 最大的优势在于抽象了原本的渲染过程,实现了跨平台的能力,而不仅仅局限于浏览器的 DOM,可以是安卓和 IOS 的原生组件,可以是小程序。
虚拟DOM工作原理: 解析模板编译为渲染函数 -> 生成VNode树 -> 对比新旧VNode -> 计算最小DOM操作 -> 更新真实DOM。
核心优势:
- 批量更新: 合并多次数据变更,减少DOM操作次数。
- 差异对比: 通过Diff算法精确找出需要更新的节点。
- 跨平台能力: 同一套VNode可以渲染到Web/Native等不同环境。
Diff算法
Diff 算法是一种对比算法,通过比较新旧虚拟DOM,得出哪个虚拟DOM发生了改变,再找出这个虚拟DOM对应的真实节点并且更新,而不用更新其他未发生改变的节点,实现精准地更新真实DOM,进而提升效率。
核心策略
- vue2采用
双指针遍历
策略,对列表节点进行逐项比较,找到可复用的节点后移动指针,对于剩余未匹配的节点,通过遍历旧列表查找对应节点,若未找到则创建新节点,找到则移动位置。当列表元素大量移动时,可能产生较多的节点或删除操作,效率低。 - vue3引用
最长递增子序列
算法,先快速对比列表头部和尾部相同节点,跳过无需修改的部分,对剩余“不确定区域”,通过计算最长递增子序列,确定可以直接复用的节点,仅对其他节点进行必要的移动或创建。大幅度减少节点移动次数,尤其在长列表或频繁变动的场景下,性能提升明显。
静态节点的处理
- vue2时,Diff过程静态节点仍会进行对比。
- vue3时,在编译阶段标记静态节点,Diff过程钟会直接跳过这些节点的比较,减少无效计算,提升效率。
同级比较
vue2、vue3都只对比同一层级的节点,不跨层级比较,若节点类型不同直接销毁旧节点,并创建新节点。
- vue2采用
key的作用
key
是给一个虚拟节点的唯一ID
,核心作用是帮助Diff算法精准判断新旧虚拟节点是否为同一节点,从而避免不必要的创建/销毁操作,提升效率。- 如果不用
key
,Vue会用一种最大减少动态元素
并且尽可能尝试就地复用
的算法,尽量不删除和添加节点,而是去修改已有节点,DOM操作增多,性能降低。