- ReactJS 教程
- ReactJS - 首页
- ReactJS - 简介
- ReactJS - 路线图
- ReactJS - 安装
- ReactJS - 特性
- ReactJS - 优点与缺点
- ReactJS - 架构
- ReactJS - 创建 React 应用
- ReactJS - JSX
- ReactJS - 组件
- ReactJS - 嵌套组件
- ReactJS - 使用新创建的组件
- ReactJS - 组件集合
- ReactJS - 样式
- ReactJS - 属性 (props)
- ReactJS - 使用属性创建组件
- ReactJS - props 验证
- ReactJS - 构造函数
- ReactJS - 组件生命周期
- ReactJS - 事件管理
- ReactJS - 创建一个事件感知组件
- ReactJS - 在 Expense Manager 应用中引入事件
- ReactJS - 状态管理
- ReactJS - 状态管理 API
- ReactJS - 无状态组件
- ReactJS - 使用 React Hooks 进行状态管理
- ReactJS - 使用 React Hooks 进行组件生命周期管理
- ReactJS - 布局组件
- ReactJS - 分页
- ReactJS - Material UI
- ReactJS - Http 客户端编程
- ReactJS - 表单编程
- ReactJS - 受控组件
- ReactJS - 非受控组件
- ReactJS - Formik
- ReactJS - 条件渲染
- ReactJS - 列表
- ReactJS - Keys
- ReactJS - 路由
- ReactJS - Redux
- ReactJS - 动画
- ReactJS - Bootstrap
- ReactJS - Map
- ReactJS - 表格
- ReactJS - 使用 Flux 管理状态
- ReactJS - 测试
- ReactJS - CLI 命令
- ReactJS - 构建和部署
- ReactJS - 示例
- Hooks
- ReactJS - Hooks 简介
- ReactJS - 使用 useState
- ReactJS - 使用 useEffect
- ReactJS - 使用 useContext
- ReactJS - 使用 useRef
- ReactJS - 使用 useReducer
- ReactJS - 使用 useCallback
- ReactJS - 使用 useMemo
- ReactJS - 自定义 Hooks
- ReactJS 高级
- ReactJS - 可访问性
- ReactJS - 代码分割
- ReactJS - Context
- ReactJS - 错误边界
- ReactJS - 转发 Refs
- ReactJS - Fragments
- ReactJS - 高阶组件
- ReactJS - 与其他库集成
- ReactJS - 性能优化
- ReactJS - Profiler API
- ReactJS - Portals
- ReactJS - 无 ES6 ECMAScript 的 React
- ReactJS - 无 JSX 的 React
- ReactJS - 协调机制 (Reconciliation)
- ReactJS - Refs 和 DOM
- ReactJS - Render Props
- ReactJS - 静态类型检查
- ReactJS - Strict Mode
- ReactJS - Web Components
- 其他概念
- ReactJS - 日期选择器
- ReactJS - Helmet
- ReactJS - 内联样式
- ReactJS - PropTypes
- ReactJS - BrowserRouter
- ReactJS - DOM
- ReactJS - 走马灯
- ReactJS - 图标
- ReactJS - 表单组件
- ReactJS - 参考 API
- ReactJS 有用资源
- ReactJS - 快速指南
- ReactJS - 有用资源
- ReactJS - 讨论
ReactJS - 协调机制 (Reconciliation)
协调机制是 React 库内部的一个流程。众所周知,React 应用会创建一个虚拟 DOM,然后根据虚拟 DOM 更新应用的实际 DOM。每当 React 接收到更新请求时,它都会首先创建一个虚拟 DOM,然后使用不同的 diff 算法将虚拟 DOM 与先前状态进行比较,只有在绝对必要时,才会更新 DOM。
尽管 diff 算法和更新 DOM 是 React 核心内部的,但了解一些内部机制将有助于我们调整应用,以最大限度地利用 React 库。
Diff 算法
本章让我们了解 React 核心应用的一些 diff 算法。
相同类型的元素
每当 React 组件将元素从一种类型更改为另一种类型(例如,从 div 更改为更具体的 p)时,整个 React 虚拟 DOM 树都会发生更改,并触发 DOM 更新。
<!-- Before --> <div> <Content /> </div> <!-- After --> <p> <Content /> </p>
此处,整个元素将被更新。
相同类型的 DOM 属性。
当元素类型相同时,React 会检查属性是否存在差异。如果 React 发现属性及其值的任何新更改,则它只会更新已更改的属性。
<!-- Before --> <div className="someClass"> <Content /> </div> <!-- After --> <div className="someOtherClass"> <Content /> </div>
此处,只会更新 DOM 实例的 class 属性。
相同类型的 DOM 属性(样式)。
当元素类型相同时,并且 React 发现样式属性存在差异时,它只会更新样式的属性。
<!-- Before --> <div style={{fontFamily: 'Arial'}} /> <p> ... </p> </div> <!-- After --> <div style={{color: 'red', fontFamily: 'Arial'}} /> <p> ... </p> </div>
此处,只会更新 div 元素样式的 color 属性。
相同类型的组件元素 - 每当 React 看到相同类型的 React 组件时,它都会调用组件的 componentWillUpdate 事件和其他更新事件以更新其状态。然后,它将调用组件的 render 方法,算法会递归。
相同类型的子元素集合 - 每当 React 看到相同类型的子元素集合时,它会按顺序检查元素是否存在差异。因此,如果我们有一个新的第一个子元素,则整个集合将被更新。
<!-- Before --> <ul> <li>Peter</li> <li>Olivia</li> </ul> <!-- After --> <ul> <li>John</li> <li>Peter</li> <li>Olivia</li> </ul>
由于第一个元素 (li) 已更新,因此此处将更新所有元素(ul 元素的子元素)。
为了解决这个问题,我们可以引入一个 key 属性,如下面的代码片段所示。React 有一个专门为此目的的 key 属性。
<!-- Before --> <ul> <li key="1">Peter</li> <li key="2">Olivia</li> </ul> <!-- After --> <ul> <li key="3">John</li> <li key="1">Peter</li> <li key="2">Olivia</li> </ul>
总结
React 尝试在每个版本中优化 diff 算法,以确保更新次数最少。更新次数越少,应用程序的性能越好。了解内部机制并遵循最佳实践进行编码,我们可以成倍地提高应用程序的性能。