我们在维护一些大型项目和一些中后端平台时,由于一些复杂的组件代码和大量的数据,性能问题也可能会浮现出来。在本文中,我们将介绍React性能优化的一些技巧
memo
React.memo是一个高阶组件,可以帮助我们避免不必要的组件渲染。它类似于React.PureComponent,但可以用于函数组件。使用React.memo包装组件时,React将会记住它的props,并在下一次渲染时进行比较。如果props没有变化,React将不会重新渲染该组件
import React, { memo } from 'react';
const App = memo(({ prop1, prop2 }) => {
return (
<div>
...
</div>
);
});
Profiler
Profiler是React官方提供的一个工具,可以帮助我们分析React应用程序的性能瓶颈。React Profiler可以显示组件渲染的时间、更新的次数和执行的函数等信息。我们可以使用React Profiler来确定哪些组件需要进行优化
import React, { Profiler } from 'react';
function onRenderCallback(
id,
phase,
actualDuration,
baseDuration,
startTime,
commitTime,
interactions
) {
console.log(`id:${id} phase:${phase} actualDuration:${actualDuration}`);
}
const App = () => {
return (
<Profiler id="App" onRender={onRenderCallback}>
...
</Profiler>
);
};
我们定义了一个名为onRenderCallback的回调函数,并将其传递给Profiler组件的onRender属性。在回调函数中,我们可以记录组件的渲染时间等信息。下面是一些属性的说明
id: 当前包裹组件的profiler的id
phase: 有两个值:"mount" (如果组件树刚加载) 或者 "update" (如果它重渲染了)之一
actualDuration: 本次更新在渲染
Profiler和它的子代上花费的时间。 这个数值表明使用 memoization 之后能表现得多好。(例如React.memo,useMemo,shouldComponentUpdate)。 理想情况下,由于子代只会因特定的 prop 改变而重渲染,因此这个值应该在第一次装载之后显著下降startTime: 本次更新中React开始渲染时间
commitTime: 本次更新中 React commit 阶段结束的时间戳。 在一次 commit 中这个值在所有的 profiler 之间是共享的,可以将它们按需分组
使用代码分割
代码分割是一种优化React应用程序性能的重要技巧。代码分割可以将应用程序拆分成多个小块,使得只有在需要时才会加载这些块。这可以减少初始加载时间,并提高应用程序的响应速度
import React, { lazy, Suspense } from 'react';
const Home = lazy(() => import('./Home'));
const App = () => {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<Home />
</Suspense>
</div>
);
};
对于使用 lazy 进行延迟加载React组件我们平时使用也比较多。这里我们还使用Suspense组件来显示加载指示器,直到组件加载完成。想要详细了解的同学可以看下 这篇文章,这里就不过多介绍
总结
在我们构建一些复杂应用的时候,这些方法和技巧可以帮助我们避免一些性能问题。有什么问题欢迎讨论