众所周知,React 能声明式编写 UI,在数据变化时能高效重新渲染合适的组件。重新渲染要经历这样的过程,先是对比前后数据的 Virtual DOM,然后计算差异以便明确如何高效的修改DOM,最后修改 DOM,把结果反映到界面上。这个过程就称为协调。
可以看到协调过程,主要是对比数据,计算差异耗费时间。要优化也要分为渲染和数据层面,细分的话有下面 3 点。
- 优化组件渲染
- 避免重复渲染
- 缓存已经计算过的数据或函数
优化组件渲染
协调过程中,对比 Virtual DOM 计算差异的算法称为 Diff 算法。它的过程如下:
- 先对比元素类型,不同则用新的元素替换旧的元素;相同,只改变相应的属性。
- 如果元素是个列表,则需要开发者提供 key 属性,这样 React 会按 key 对比元素。 不然 React 只会从上到下按顺序对比元素。
知道了 diff 算法,那我们的优化策略也就有了。
- 尽量不要改变组件的元素类型,尤其是上层组件的元素类型。
- 渲染列表时,给 React 提供稳定的,唯一的 key。
避免重复渲染
React 组件在数据变化时要重新渲染。我们从数据变化角度出发,看看如何优化。
核心思路就是,只在数据变化渲染组件。React 和 Redux 提供了很多自动对比和手动对比的手段。
自动对比数据变化有: React 类组件继承 PureComponent,React-redux 的 connect。
手动对比数据变化有:shouldComponentUpdate, React.memo。
缓存数据
除了对比数据,还可以把已经计算过的数据或函数缓存或者说记忆起来,省去计算的过程。
为此 React Hook 提供了 2 个 返回记忆结果的 API,useMemo,useCallback