Vue2.x 和 Vue3.x 渲染器的 diff 算法
diff 算法有以下过程
同级比较,再比较子节点
先判断一方有子节点一方没有子节点的情况(如果新的 children 没有子节点,将旧的子节点移除)
比较都有子节点的情况(核心 diff)
递归比较子节点
正常 Diff 两个树的时间复杂度是 O(n^3)
,但实际情况下我们很少会进行跨层级的移动 DOM,所以 Vue 将 Diff 进行了优化,从 O(n^3) -> O(n)
,
只有当新旧 children 都为多个子节点时才需要用核心的 Diff 算法进行同层级比较。
Vue2 Diff
Vue2 的核心 Diff 算法采用了双端比较的算法,同时从新旧 children 的两端开始进行比较,借助 key 值找到可复用的节点,再进行相关操作。
相比 React 的 Diff 算法,同样情况下可以减少移动节点次数,减少不必要的性能损耗,更加的优雅。
Vue3 Diff
Vue3.x 借鉴了 ivi 算法
和 inferno 算法
在创建 VNode 时就确定其类型,以及在 mount/patch
的过程中采用位运算来判断一个 VNode 的类型,在这个基础之上再配合核心的 Diff 算法,
使得性能上较 Vue2.x 有了提升。(实际的实现可以结合 Vue3.x 源码看。)
该算法中还运用了动态规划的思想
求解最长递归子序列。