本文主要讲解实战项目中React性能优化的方法,主要分为三个大的方面:减少不必要的组件更新、组件优化以及tree-shaking,共11个方法
一、减少不必要组件更新
以下是一些可以避免在 React 提交阶段进行不必要重新渲染的方法:
1、使用 React.memo
(对于函数组件)和 PureComponent
(对于类组件)
-
React.memo
:
React.memo
是一个高阶组件,用于包装函数组件。它通过对组件的props
进行浅层比较来决定是否重新渲染组件。
示例:import React from 'react'; const MyComponent = React.memo(({ data }) => { // 组件渲染逻辑 return <div>{ data}</div>; });
当
data
的引用没有发生变化时,组件将不会重新渲染。 -
PureComponent
(对于类组件):
PureComponent
会对props
和state
进行浅层比较。如果它们没有变化,组件将不会重新渲染。
示例:
以下是一个在类组件中使用PureComponent
的示例,包括数据传递和更新:
import React, {
PureComponent } from 'react';
class MyComponent extends PureComponent {
// 构造函数,初始化状态
constructor(props) {
super(props);
this.state = {
count: 0,
name: 'Initial Name',
};
}
// 处理点击事件,更新状态
handleClick = () => {
// 示例 1:更新数字状态
this.setState({
count: this.state.count + 1 });
// 示例 2:更新字符串状态(如果 name 是从父组件传递的 props 且未变化,不会触发重新渲染)
// 假设 name 是从父组件传递的 props,以下更新不会触发重新渲染(如果 name 未变化)
// this.setState({ name: this.props.name });
};
render() {
return (
<div>
<p>Count: {
this.state.count}</p>
<p>Name: {
this.state.name}</p>
<button onClick={
this.handleClick}>Increment Count</button>
</div>
);
}
}
// 父组件
class ParentComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'Parent Name',
};
}
handleNameChange = () => {
this.setState({
name: 'Updated Name' });
};
render() {
return (
<div>
<MyComponent name={
this.state.name} />
<button onClick={
this.handleNameChange}>Change Name</button>
</div>
);
}
}
export default ParentComponent;
在这个例子中:
-
MyComponent
是一个继承自PureComponent
的类组件。它有一个count
状态用于数字的递增展示,还有一个name
状态(也可以是从父组件传递的props
)用于展示字符串。 -
在
render
方法中,展示了count
和name
的值,并有一个按钮用于触发count
的递增。 -
ParentComponent
是父组件,它有一个name
状态,并将其传递给MyComponent
。还有一个按钮用于更改name
的状态。
PureComponent
会对 props
和 state
进行浅层比较。如果 props
或 state
的引用没有变化,组件将不会重新渲染。在上面的例子中,如果 MyComponent
接收到的 props.name
没有变化,并且 state
中的 count
没有更新,MyComponent
就不会重新渲染。
注意事项:
PureComponent
的浅层比较对于基本数据类型(如数字、字符串、布尔值)是有效的,但对于复杂数据类型(如对象、数组),它只会比较引用。如果对象或数组的内容发生变化,但引用不变,PureComponent
可能不会检测到变化。在这种情况下,可以使用immutable.js
或手动在shouldComponentUpdate
中进行深层比较。- 如果组件的
props
或state
变化频繁且计算成本不高,或者需要进行深层比较,可能不需要使用PureComponent
。
2、使用 useCallback
和 useMemo
-
useCallback
:
useCallback
用于记忆函数,确保传递给子组件的函数在依赖项不变的情况下不会重新创建。
示例:import React, { useState, useCallback } from 'react'; function ParentComponent() { const [count, setCount