第 9 章 简单 Diff 算法
霍春阳(HcySunYang)
从本章开始,我们将介绍渲染器的核心 Diff 算法。简单来说,当新旧 vnode 的子节点都是一组节点时,为了以最小的性能开销完成更新操作,需要比较两组子节点,用于比较的算法就叫作 Diff 算法。我们知道,操作 DOM 的性能开销通常比较大,而渲染器的核心 Diff 算法就是为了解决这个问题而诞生的。
9.1 减少 DOM 操作的性能开销
核心 Diff 只关心新旧虚拟节点都存在一组子节点的情况。在上一章中,我们针对两组子节点的更新,采用了一种简单直接的手段,即卸载全部旧子节点,再挂载全部新子节点。这么做的确可以完成更新,但由于没有复用任何 DOM 元素,所以会产生极大的性能开销。
以下面的新旧虚拟节点为例:
按照之前的做法,当更新子节点时,我们需要执行 6 次 DOM 操作:
卸载所有旧子节点,需要 3 次 DOM 删除操作;
挂载所有新子节点,需要 3 次 DOM 添加操作。
但是,通过观察上面新旧 vnode 的子节点,可以发现:
更新前后的所有子节点都是 p 标签,即标签元素不变;
只有 p 标签的子节点(文本节点)会发生变化。
例如,oldVNode 的第一个子节点是一个 p 标签,且该 p 标签的子节点类型是文本节点,内容是 '1'。而 newVNode 的第一个子节点也是一个 p 标签,它的子节点的类型也是文本节点,内容是 '4'。可以发现,更新前后改变的只有 p 标签文本节点的内容。所以,最理想的更新方式是,直接更新这个 p 标签的文本节点的内容。这样只需要一次 DOM 操作,即可完成一个 p 标签更新。新旧虚拟节点都有 3 个 p 标签作为子节点,所以一共只需要 3 次 DOM 操作就可以完成全部节点的更新。相比原来需要执行 6 次 DOM 操作才能完成更新的方式,其性能提升了一倍。
公开
同步至部落
取消
完成
0/2000
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
![](https://static001.geekbang.org/resource/image/d0/e4/d0880927e2a522a038be2d04bf19dfe4.png)
本文深入介绍了渲染器核心 Diff 算法,旨在解决更新操作中的性能开销问题。首先,通过比较新旧虚拟节点的子节点,提出了一种更新方式,即只更新发生变化的部分,从而减少了 DOM 操作次数,提升了性能。随后,作者指出了该方法存在的问题,并提出了遍历长度较短的一组子节点,并根据新旧两组子节点的长度关系进行挂载或卸载的优化方案。进一步讨论了 DOM 复用与 key 的作用,提出了通过 DOM 的移动来完成子节点的更新,以减少不必要的 DOM 操作。通过介绍简单直接的 Diff 算法,以及对其进行优化的思路,为读者提供了一种有效提升渲染性能的方法。总体来说,本文内容涉及了虚拟节点的比较、DOM 操作的优化以及节点复用等技术特点,对于想要提升渲染性能的开发者来说,是一篇值得阅读的技术文章。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Vue.js 设计与实现》
《Vue.js 设计与实现》
立即购买
登录 后留言
精选留言
由作者筛选后的优质留言将会公开显示,欢迎踊跃留言。
收起评论