Skip to content

简单介绍下React中的 diff 算法

参考答案:

diff 算法主要基于三个规律:

  • DOM 节点的跨层级移动的操作特别少,可以忽略不计
  • 拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构
  • 对于同一层级的一组子节点,可以通过唯一的 id 进行区分

tree diff

因为上面的三个策略中的第一点, DOM 节点的跨级操作比较少,那么 diff 算法只会对相同层级的 DOM 节点进行比较。如果发现节点不存在 那么会将该节点以及其子节点完全删除,不会再继续比较。如果出现了 DOM 节点的跨层级的移动操作,那么会删除改节点以及其所有的子节点,然后再移动后的位置重新创建。

component diff

如果是同一类型的组件,那么会继续对比 VM 数

如果不是同一类型的组件,那么会将其和其子节点完全替换,不会再进行比对

同一类型的组件,有可能 VM 没有任何的变化,如果可以确定的知道这点,那么就可以节省大量的 diff 时间,所以用户可以设置 shouldComponentUpdate() 来判断是否需要进行 diff 算法。

element diff

当节点处于同一层级的时候时,有三种操作:INSERT_MAKEUP插入、 MOVE_EXISTING 移动、 REMOVE_NODE 删除

这里 React 有一个优化策略,对于同一层级的同组子节点,添加唯一的 key 进行区分。这样的话,就可以判断出来是否是移动节点。通过 key 发现新旧集合中的节点都是相同的节点,就只需要进行移动操作就可以。

题目要点:

React 的 diff 算法用于高效地更新虚拟 DOM 和实际 DOM 的过程。它的主要目标是最小化对实际 DOM 的操作,从而提高性能。以下是简单介绍:

Diff 算法概述

  1. 虚拟 DOM 树比较

    • 比较:React 使用虚拟 DOM 树来表示组件的当前状态。每当组件的状态或属性发生变化时,React 会创建一个新的虚拟 DOM 树并将其与旧的虚拟 DOM 树进行比较。
    • 目标:通过比较旧的虚拟 DOM 树和新的虚拟 DOM 树,找出需要更新的部分。
  2. 算法原理

    • 树的层级比较:React diff 算法采用逐层比较的策略。它只比较同一层级的节点,而不是整个树。这样可以提高性能,避免不必要的计算。
    • 同层级节点比较:在同一层级上,React 通过比较节点的类型和属性来判断节点是否发生变化。如果节点类型相同,React 会进一步比较属性和子节点。
  3. 优化策略

    • 唯一 Key 属性:对于列表中的元素,React 使用 key 属性来标识每个元素,帮助算法识别和匹配元素,避免重新渲染整个列表。
    • 组件更新:对于函数组件和类组件,React 会根据组件的 render 方法返回的新虚拟 DOM 和之前的虚拟 DOM 进行比较,只有在有必要时才会更新实际 DOM。
  4. 更新策略

    • 局部更新:通过比较,React 能够精确地确定哪些部分需要更新,只对这些部分进行实际 DOM 更新,从而减少性能开销。
    • 重用节点:在可能的情况下,React 会重用现有的 DOM 节点,减少不必要的 DOM 操作。

总结

React 的 diff 算法通过对虚拟 DOM 树的逐层比较和局部更新策略,能够高效地更新实际 DOM,减少性能开销。使用唯一的 key 属性和优化的节点比较机制,使得算法能够快速识别变化并进行最小化的 DOM 更新。