zl程序教程

您现在的位置是:首页 >  Javascript

当前栏目

React性能优化

2023-02-25 18:16:06 时间

参数传递优化

父组件给子组件传递对象类型的参数时,应该在render()内部先将对象定义。不然每一次使用子组件时都会生成新的对象进行传递。

错误示范:

正确示范:

事件绑定优化

尽量避免使用匿名函数的形式绑定事件,除非你需要传递当前作用域参数

错误示范:

正确示范:

第一种再次执行时都要再渲染一编render()里的bind函数和函数声明式,而③的绑定函数只执行一次,并不会每次执行时都进行调用

组件渲染优化

父组件重新渲染,默认子组件也会重新渲染。如果子组件接收的props没有变化,则无须重新渲染,否则会造成性能浪费,子组件内部应该对比传递进来的props是否变化进行是否渲染

类组件在shouldComponentUpdate声明周期里对比props的变化,或者使用 React.PureComponent 替换 React.Component

函数组件使用useMemo和useCallback来缓存不需要重新渲染的属性或函数

数据渲染,key的优化

渲染数组形式的数据,遍历时React会要求你为每一个数据值添加Key。

而Key必须时独一无二的,在选取Key值时尽量不要用索引号。

因为如果当数据的添加方式不是顺序添加,而是以其他方式(逆序,随机等),会导致每一次添加数据,每一个数据值的索引号都不一样,这就导致了Key的变化。

而当Key变化时,React就会认为这与之前的数据值不相同,会多次执行渲染,会造成大量的性能浪费。所以只在万不得已时,才将数据的Key设为索引号。

离开组件销毁定时器

如果组件中使用到了定时器,应该在组件销毁周期里将定时器即使清除 ,否则会产生内存泄漏

在class组件中的写法

1import React from "react";
2
3class Clock extends React.Component {
4  constructor(props) {
5    super(props);
6    this.state = { date: new Date() };
7  }
8
9  componentDidMount() {
10    this.time = setInterval(() => {
11      this.setState({ date: new Date() });
12      console.log("如果你已离开Clock组件,此定时器应该被销毁");
13    }, 1000);
14  }
15
16  componentWillUnmount() {
17    clearInterval(this.time);
18  }
19
20  render() {
21    const { date } = this.state;
22    return (
23      <div>
24        <h1>Hello, world!</h1>
25        <h2>
26          现在是
27          {" "}
28          {date.toLocaleTimeString()}
29        </h2>
30      </div>
31    );
32  }
33}
34
35export default Clock;
36

在函数组件中的写法:

1import React, { useState, useEffect } from "react";
2
3function Clock() {
4  const [date, setDate] = useState(new Date());
5
6  useEffect(() => {
7    const time = setInterval(() => {
8      setDate(new Date());
9      console.log("如果你已离开Clock组件,此定时器应该被销毁");
10    }, 1000);
11
12    // 模拟组件销毁时生命周期
13    return () => clearInterval(time);
14  }, []);
15
16  return (
17    <div>
18      现在是:
19      {date.toLocaleTimeString()}
20    </div>
21  );
22}
23
24export default Clock;
25

代码层面

使用return null而不是CSS的display:none来控制节点的显示隐藏。保证同一时间页面的DOM节点尽可能的少。

props和state的数据尽可能简单明了,扁平化

利用 shouldComponentUpdate 和 PureComponent 避免过多 render function; render里面尽量减少新建变量和bind函数,传递参数是尽量减少传递参数的数量。 尽量将 props 和 state 扁平化,只传递 component 需要的 props(传得太多,或者层次传得太深,都会加重shouldComponentUpdate里面的数据比较负担),慎将 component 当作 props 传入