React进阶笔记【6_栈调和】

2022/4/5 ReactJS

React 16+ 太香了,要想从根本上理解 React 16 大改版背后的动机,就需要了解 React 15 的运作机制:栈调和算法(Reconciliation)。

# 调和 和 Diff

Virtual DOM 是一种编程理念。在这个概念里,UI以一种理想化的,或者说 “虚拟的” 表现形式被保存于内存中,并通过如 ReactDOM 等类库使之与 “真实的” DOM 同步。这一过程叫做 协调(调和)。

—— React 官方

调和指的是从虚拟 DOM 映射到真实 DOM 的过程, 调和是 “使一致” 的过程,而 Diff 是 “找不同” 的过程, 所以 Diff 只是调和的其中一个环节。

React 源码大致划分为三个模块:Core、Renderer、Reconciler,其中 Reconciler(调和器)所做的工作包括组件的挂载、卸载、更新等过程,Diff 就出现在更新过程。

# Diff 的设计思想

OJ 中相对理想的复杂度一般是 O(1)O(n),当复杂度攀升到 O(n2) 时,就要思考寻找性能优化的手段。

React 在此总结了两个规律,从而将 O(nm) 转换为 O(n)

  1. 若两个组件属于同一个类型,它们将拥有相同的 DOM 树形结构。
  2. 处于同一层级的一组子节点,可以通过设置 key 作为唯一标识,从而维持各个节点在不同渲染过程中的稳定性。

# Diff 的拆分和解读

  1. Diff 算法性能突破的关键点在于 “分层对比”

    “DOM 节点之间的跨层级操作并不多,同层级操作才是主流”,所以 React 的 Diff 过程直接放弃了跨层级之间的节点比较,只针对相同层级的节点作对比。

  2. 类型一致的节点才有继续 Diff 的必要性

    本着 “主要矛盾” 的基本原则,React 认为,只有同类型的组件,才有进一步对比的必要性。

  3. key 属性的设置,可以帮助尽可能重用同一层级的节点

    key 是用来帮助 React 识别哪些内容被修改、添加、删除。key 需要写在数组渲染出来的元素内部,并且需要一个稳定的值。这里的稳定很重要,因为如果 key 发生了改变,React 就会触发 UI 的重渲染。