引言
普适的性能优化手段对于 React 同样奏效
以 React 组件的形式来组织逻辑
组件允许我们将 UI 拆分为独立可复用的代码片段
并对每个片段进行独立构思
- 使用 shouldComponentUpdate 规避冗余的更新逻辑
- PureComponent + Immutable.js
- React.memo 与 useMemo
朴素思路:善用 shouldComponentUpdate
是一个 React 类组件的一个生命周期
shouldComponentUpdate(nextProps, nextState)
React 组件会根据 shouldComponentUpdate 的返回值
来决定是否执行该方法之后的生命周期
进而决定是否对组件进行 re-render(重渲染)
默认值为 true,也就是说“无条件 re-render”
通过一个 Demo,来感受一个如何解决问题!
这个 Demo 演示的就是在父组件被渲染时,子组件也都会被 re-render。
如果在 shouldComponent 函数中增加一下对比,那么就可以避免掉这次 re-render。
进阶玩法:PureComponent + Immutable.js
PureComponent: 提前帮你安排好更新判定逻辑
shouldComponentUpdate 虽然一定程度上帮助我们解决了这个性能问题
但在写了不计其数个 shouldComponentUpdate 逻辑之后,难免会怀疑人生
React 15.3 新增了一个叫 PureComponent 的类
PureComponent 将会在 shouldComponentUpdate 中
对组件更新前后的 props 和 state 进行浅比较
并根据浅比较的结果,决定是否需要继续更新流程
浅比较:值类型比较值是否相等,引用类型比较其引用是否相等
数据类型为引用类型
- 若数据内容没变,但是引用变了
那么浅比较仍然会认为“数据发生了变化”,进而触发一次不必要的更新导致过度渲染。
- 若数据内容变了,但是引用没变
那么浅比较则会认为“数据没有发生变化”,进而阻断一次更新,导致不渲染
Immutable: “不可变值”让“变化”无处遁形
PureComponent 浅比较带来的问题
本质上是对“变化”的判断不够精准导致的
Immutable.js 是对“不可变值”这一思想的实践
- 持久性数据 指的是这个数据只要被创建出来了,就不能被更改
我们当前数据的任何修改动作,都会导致一个新的对象返回
以上都是类组件的优化思路
函数组件的性能优化:React.memo 和 useMemo
在函数组件中,有没有什么通用的手段可以阻止 “过度 re-render” 的发生呢?
“函数版” 的 shouldComponentUpdate/PureComponent -- React.memo
React.memo:“函数” shouldComponentUpdate/PureComponent
function Demo(props) (xxx)
function areEqual(prevProps, nextProps) { }
export default React.memo(FunctionDemo, areEqual)
React.memo 控制是否需要渲染一个组件
useMemo 控制的则是是否需要重要执行某一段逻辑
useMemo: 更加“精细”的 memo
这个函数的作用主要就是缓存一些昂贵的计算,如果依赖没变的话,使用上次计算的结果
const renderCount = useMemo(() => (<Text>{count}</Text>), [count])
const renderText = useMemo(() => (<Text>{text}</Text>), [text])
const Comp = (props) => {
return (
{ renderCount() }
{ renderText() }
)
}
可以在页面内更加精细的重绘
总结
学习了 React 组件性能优化中最重要的 3 个思路
这3个思路不仅可以作为大家日常实战的知识储备
更能够帮助你在面试场景下做到言之有物
若你能把握好本讲的内容,选择其中一个或多个方向深入探究,相信你已经超越了大部分的同行