react 组件更新分为两个阶段:render 阶段和 commit 阶段;因此可以从两个方面来优化组件性能:
阻止组件重渲染 rerender
- 对于 class 组件,使用 shouldComponentUpdate 来阻止 render 方法的执行
- 对于函数式组件,使用 React.memo 来阻止函数式组件的重复执行
- 由于函数式组件父组件的更新,会导致全部子组件更新(在没有使用 React.memo 的情况下);所以需要尽可能的拆分组件,配合使用 React.memo ,使某一需要更新的子组件不会影响其他子组件
使用 React.memo
- 当父组件传递给子组件的 props 没有实际变更时,在父组件中使用 useCallback、useMemo 来保证传递给子组件的引用类型的 props 没有变化;子组件使用 React.memo 才能阻止重复执行;
- 函数组件的参数
commit 阶段浏览器渲染
- React.Profiler 的使用
<React.Profiler id='index' onRender={callback}>
<Compoent />
</React.Profiler>
let commitCounter = 0;
function callback(id, phase, actualTime,baseTime,startTime,commitTime,interactions) {
commitCounter ++;
console.log('countRender: ', countRender);
console.log(id,phase,actualTime,baseTime,startTime,commitTime,interactions);
}
使用 React.Profiler 可以知道每一次 commit 浏览器渲染的时间;根据 commitCounter 和 React devtool 可以查看具体的 commit 渲染的火焰图:
根据火焰图,可以知道每次 commit 每个组件的渲染耗时,以及什么原因导致组件渲染