React中的Diff 策略,你真的了解吗?图解Diff 策略

863 阅读3分钟

“我正在参加「掘金·启航计划」”

前言

当我们学习React的时候,总少不了对React Diff的讨论。React中的Diff原理 是非常重要的一个知识,面试中也会经常问到,所以一定要掌握好React中的Diff 策略,这篇文章可以让我们快速入门并理解React中的Diff 策略,就让我们来React Diff一把梭!

diff算法

  • diff 作为 Virtual DOM 的加速器,其算法上的改进优化是 React 整个界面渲染的基础和性能保障,同时也是 React 源码中最神秘、最不可思议的部分。

  • React 中最值得称道的部分莫过于 Virtual DOM 模型与 diff 的完美结合,特别是其高效的diff 算法,可以让用户无需顾忌性能问题而“任性自由”地刷新页面,让开发者也可以无需关心Virtual DOM 背后的运作原理。因为 diff 会帮助我们计算出 Virtual DOM 中真正变化的部分,并只针对该部分进行原生 DOM 操作,而非重新渲染整个页面,从而保证了每次操作更新后页面的高效渲染。因此,Virtual DOM 模型与 diff 是保证 React 性能口碑的幕后推手。

  • diff 算法也并非其首创。正是因为该算法的普适度高,就更应该认可 React 针对 diff 算法优化所做的努力与贡献,这更能体现 React 创作者们的魅力与智慧!

diff 策略

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

基于以上策略,React 分别对 tree diff、component diff 以及 element diff 进行算法优化。事实也证明这 3 个前提策略是合理且准确的,它保证了整体界面构建的性能。

1.tree diff

  • React 对树的算法进行了简洁明了的优化,即对树进行分层比较,两棵树只会对同一层次的节点进行比较

image.png

  • 当出现节点跨层级移动时,并不会出现想象中的移动操作,而是以 A 为根节点的树被整个重新创建

image.png

2.component diff

  • 如果是同一类型的组件,按照原策略继续比较 virtual DOM tree
  • 如果不是,则将该组件判断为 dirty component ,从而替换整个组件下的所有子节点

image.png

3.element diff

  • 当节点处于同一层级时,React diff 提供了三种节点操作,分别为:INSERT(插入)、MOVE(移动)和 REMOVE(删除)
  • INSERT 新的 component 类型不在老集合里, 即是全新的节点,需要对新节点执行插入操作
  • MOVE 在老集合有新 component 类型,就需要做移动操作,可以复用以前的 DOM 节点
  • REMOVE 老 component 不在新集合里的,也需要执行删除操作

4.key

image.png

image.png

image.png

结尾

看到这里,文章就已经结束了。相信这篇文章能够让你对React diff有了一定的了解,同时也能对React diff里面三个diff策略有了一定的了解,希望这篇文章能在学习、工作或者面试带给你一点点帮助。后续也会出更多关于前端的、有意思的内容,大家可以期待一下。