性能优化的一般思路:将**「变化的部分」与「不变的部分」分离 什么是「变化的部分」**?
- State
- Props
- Context
命中**「性能优化」的组件可以不通过reconcile生成wip.child**,而是直接复用上次更新生成的wip.child。 总结起来有两点:
- 性能优化的思路是将**「变化的部分」与「不变的部分」**分离
命中性能优化的组件的子组件(而不是他本身)不需要render
已经触发更新,在更新过程中极大复用之前的fiber bailout四要素:
- props不变
比较props变化是通过「全等比较」,使用React.memo后会变为「浅比较」
- state不变
两种情况可能造成state不变: 不存在update 存在update,但计算得出的state没变化
- context不变
- type不变
作用:保存一个fiberNode中「所有未执行更新对应的lane」 延伸功能:fiber.childLanes,保存一个fiberNode子树中「所有未执行更新对应的lane」
- 产生:enqueueUpdate
- 消费:beginWork
- 未消费时的重置:processUpdateQueue
状态更新前后没有变化,那么没有必要触发更新,为此需要做:
- 计算更新后的状态
- 与更新前的状态做比较
通常情况下,「根据update计算state」发生在beginWork,而我们需要在「触发更新时」计算状态 只有满足「当前fiberNode没有其他更新」才尝试进入eagerState策略。
demo:performance/memo.tsx 作用:让「props的全等比较」变为「props的浅比较」 本质:在子组件与父组件之间增加一个MemoComponent,MemoComponent通过「props的浅比较」命中bailout策略
demo:performance/Hook.tsx demo:performance/useMemo.tsx
- useCallback:缓存函数
- useMemo:缓存变量(特殊用法:手动bailout)