认识
一、认识
React
性能优化思路为: 将变化的部分与不变的部分分离。变化的部分可以为: state
、props
、context
。命中性能优化的组件可以不通过 reconcile
生成 workInProgress.child
而是直接复用上次更新生成的 workInProgress.child
。因此 React
源码 中的性能优化总结起来有两点:
-
将变化的部分与不变的部分分离
-
命中性能优化的组件的子组件(不是自身)不需要
render
React
性能优化策略如下:
-
bailout
策略: 命中bailout
性能优化策略的组件可以不通过reconcile
生成workInProgress.child
, 而是复用上次更新生成的workInProgress.child
, 减少不必要的子组件render
。 -
eagerState
策略: 状态更新前后没有变化, 那么没有必要触发更新, 不必要的更新, 没必要开启后续调度流程
二、bailout
bailout
性能优化策略 存在于 beginWork
中, 命中 bailout
性能优化策略的组件可以不通过 reconcile
生成 workInProgress.child
, 而是复用上次更新生成的 workInProgress.child
, 减少不必要的子组件 render
。bailout
四要素为:
-
props
不变: 比较props
变化是通过全等比较, 使用React.memo
后会变为浅比较。 -
state
不变: 两种情况可能造成state
不变:-
不存在
update
-
存在
update
, 但计算得出的state
没变化
-
-
context
不变 -
type
不变
bailout
性能优化策略表现为: 如果命中了 bailout
性能优化策略, 那么不会调用 reconcileChildren
生成新的 workInProgress.child
三、eagerState
eagerState
性能优化策略 状态更新前后没有变化, 那么没有必要触发更新, 不必要的更新, 没必要开启后续调度流程。为此需要做:
-
当前产生的
update
是当前fiber
的第一个update
: 通常情况下, 根据update
计算state
发生在beginWork
, 而我们需要在 触发更新时 计算状态, 只有满足 当前fiberNode
没有其他更新 才尝试进入eagerState
策略, 避免存在有些update
因为优先级不够被跳过的情况。if (
fiber.lanes === NoLanes &&
(current == null || current.lanes === NoLanes)
) {
} -
计算更新后的状态
-
与更新前的状态做比较
eagerState
性能优化策略表现为: 如果命中了 eagerState
性能优化策略, 那么不会调用 scheduleUpdateOnFiber
开启新的调度流程。