🔥 这些避免React组件重复渲染的手段你都知道吗?

12,121 阅读12分钟

使用React已经三年了,在这三年里面也沉积了不少关于React代码优化的最佳实践,今天先写一部分出来和大家分享分享。后续看文章是否受欢迎再觉得是否分享后面的。

这篇文章的每一个最佳实践我都会提供两个例子,一好一坏作为对比,和提供.gif 图片预览。

本片文章主要对以下这三种情况进行优化:

  • 父组件更新导致子组件渲染
  • Props的错误写法导致组件渲染
  • Context的更新导致组件渲染

看完文章如果你觉得对你有了帮助,请帮忙点个赞,你的点赞是我创作的最大动力。评论点赞可以获得源码!!

父组件更新导致子组件渲染

Class 示例

❎ 错误示例预览

1.classBad.gif

❎ 错误示例

import React, { Component } from "react";
class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  render() {
    const { count } = this.state;
    return (
      <div className="parent">
        <h5>错误示例</h5>
        <p>父组件Count--{count}</p>
        <button onClick={this.handleClick}>增加</button>
        <Son />
      </div>
    );
  }
}

class Son extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("子组件重新渲染了!!");
    return <div className="son">子组件</div>;
  }
}

export { Parent, Son };

✋🏻 点击查看在线 demo

在本示例中, 父组件中的state 发生变化导致了子组件的重新渲染,这样写的代码是一个很正常的写法,但是认真说起来,还是会造成性能上的浪费,毕竟子组件重新渲染了!接下来我们看看怎样解决这个问题!

说明: 本示例并不是说要杜绝写这样的代码,其实优化也是要看场景的!!

✅ 正确示例 1

import React, { Component, PureComponent } from "react";
class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  render() {
    const { count } = this.state;
    return (
      <div className="parent">
        <h5>正确示例1</h5>
        <p>父组件Count--{count}</p>
        <button onClick={this.handleClick}>增加</button>
        <Son />
      </div>
    );
  }
}

class Son extends PureComponent {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("子组件重新渲染了!!");
    return <div className="son">子组件</div>;
  }
}

export default Parent;

✋🏻 点击查看在线 demo

在这个例子中我们主要是借用了 PureComponent 继承这个类,React会自动帮我们执行 shouldComponentUpdate 对 Props 进行浅比较优化更新。

说明: 其实认真的讲,在React中组件会被 React.createElement(Son) 执行,所得到的组件的Props引用每次都是新的,因此会引发重新渲染!

✅ 正确示例 2

import React, { Component } from "react";
class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  render() {
    const { count } = this.state;
    const { children } = this.props;
    return (
      <div className="parent">
        <h5>正确示例2</h5>
        <p>父组件Count--{count}</p>
        <button onClick={this.handleClick}>增加</button>
        {children}
      </div>
    );
  }
}

export default Parent;

<Parent>
  <Son />
</Parent>

✋🏻 点击查看在线 demo

在本示例的优化中,我们将有状态组件和无状态组件进行分离,使用 children 将无状态组件传入。这样会避免无意义的重复渲染! 那为什么这样写会避免重新渲染呢? 因为直接在状态组件中使用children直接渲染子组件可以避免在状态组件中React使用React.createElement(Son) 渲染子组件!!这样也可以做到优化!

✅ 正确示例 3

import React, { Component, memo } from "react";
import { Son } from "./Bad";

const MemoSon = memo(() => <Son></Son>);

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  render() {
    const { count } = this.state;
    return (
      <div className="parent">
        <h5>正确示例3</h5>
        <p>父组件Count--{count}</p>
        <button onClick={this.handleClick}>增加</button>
        <MemoSon />
      </div>
    );
  }
}

export default Parent;

✋🏻 点击查看在线 demo

在本示例中其实实现优化的思想和示例1 所提到的思想类似, 我们借用了memo 函数,这个函数其实是为Function组件 准备的优化手段。我们在这里也是厚着脸皮强行使用一下!!,避免重新渲染的思想其实也是对比Props的引用。决定是否渲染!!

✅ 正确示例 4

import React, { Component, useState, Fragment } from "react";
import { Son } from "./Bad";

const ClickCount = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <Fragment>
      <div>
        <h5>正确示例4</h5>
        <p>父组件Count--{count}</p>
        <button onClick={handleClick}>增加</button>
      </div>
    </Fragment>
  );
};

class Parent extends Component {
  constructor(props) {
    super(props);
  }

  render() {
    return (
      <div className="parent">
        <ClickCount />
        <Son />
      </div>
    );
  }
}

export default Parent;

✋🏻 点击查看在线 demo

本示例中,我们的优化手段主要是将状态组件提出去成一个组件,这样状态的改变就和子组件分离开了。也可以避免子组件的重新渲染!!

说明: 这个优化手段认真讲还是用到挺少的,看情况使用吧!!

Hooks 示例

错误示例预览

1.HooksBad.gif

❎ 错误示例

import { useState } from "react";
const Son = () => {
  console.log("子组件重新渲染了!!");
  return <div className="son">子组件</div>;
};

const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>错误示例</h5>
      <p>父组件Count--{count}</p>
      <button onClick={handleClick}>增加</button>
      <Son />
    </div>
  );
};

export { Son, Parent };

✋🏻 点击查看在线 demo

对于Hooks来说上面的写法也是非常正常的写法,但是与Class组件相比,Function组件 的特性是每一次的组件重新渲染,都会重新执行一次函数。而对于Class组件来说,只会执行一遍 new Class ,其实仔细想想还是挺可怕的。对函数组价来说,每次的执行都意味着新的上下文,新的变量,新的作用域。因此我们要更加注重函数组件的性能优化。

✅ 正确示例 1

import { useState } from "react";

const Parent = ({ children }) => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>正确示例1</h5>
      <p>父组件Count--{count}</p>
      <button onClick={handleClick}>增加</button>
      {children}
    </div>
  );
};

export default Parent;

<Parent>
  <Son />
</Parent

✋🏻 点击查看在线 demo

在本示例中,我们使用了children 直接渲染子组件,原理其实在上面Class组件示例中已经讲过了,这样的优化也能避免无意义的渲染。

说明: 认真的讲,结合函数组件的特性这个优化手段其实是治标不治本的!

✅ 正确示例 2

import { useState, useMemo } from "react";
import { Son } from "./Bad";
const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>正确示例2</h5>
      <p>父组件Count--{count}</p>
      <button onClick={handleClick}>增加</button>
      {useMemo(
        () => (
          <Son />
        ),
        []
      )}
    </div>
  );
};

export default Parent;

✋🏻 点击查看在线 demo

在本示例中我们使用了useMemo 这个优化Hook,我们将 Son 组件进行缓存,只有当依赖改变,我们再去重新执行函数完成重新渲染,其他时机保证memoized相同,这样有助于避免在每次渲染时都进行高开销的计算。也避免了 每次在子组件中 都要重新声明变量,函数,作用域等。

说明:我觉得这个优化手段绝对称得上神来之笔,因为 useMemo 保存了组件的引用,没有重新执行函数组件,因此避免了组件内的变量,函数声明,和作用域的声明。从而优化了性能。 Nice!!

✅ 正确示例 3

import { useState, memo } from "react";
import { Son } from "./Bad";

const SonMemo = memo(Son);

const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>正确示例3</h5>
      <p>父组件Count--{count}</p>
      <button onClick={handleClick}>增加</button>
      <SonMemo />
    </div>
  );
};

export default Parent;

✋🏻 点击查看在线 demo

本示例中我们运用了memo这个api, 主要是对比props引用是否改变,从而避免子组件的重新渲染!

Props的错误写法导致组件渲染

Class 示例

❎ 错误示例预览

2.ClassBad.gif

❎ 错误示例

import React, { Component, PureComponent } from "react";

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  render() {
    const { count } = this.state;
    return (
      <div className="parent">
        <h5>错误示例</h5>
        <p>父组件Count--{count}</p>
        <button onClick={this.handleClick}>增加</button>
        <Son componentDetails={{ name: "子组件" }} anyMethod={() => {}} />
      </div>
    );
  }
}

class Son extends PureComponent {
  constructor(props) {
    super(props);
  }
  render() {
    const { componentDetails, anyMethod } = this.props;
    console.log("Son -> render -> anyMethod", anyMethod);
    console.log("Son -> render -> componentDetails", componentDetails);
    return <div className="son">{componentDetails?.name}</div>;
  }
}

export { Parent, Son };

✋🏻 点击查看在线 demo

这个示例中Props的传递直接是错误的写法,为什么呢?因为组件的渲染主要是通过监听Props和State的变化进行渲染的,那在这个示例传的props每次都是一个新的对象,因为引用的不同,每次的父组件的渲染都会导致子组件的渲染。 因此这种写法造成的重新渲染实数不该!!

那我们应该怎么写呢?

✅ 正确示例 1

import React, { Component, PureComponent } from "react";

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      componentDetails: { name: "子组件" },
    };
  }
  handleClick = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };
  anyMethod = () => {};
  render() {
    const { count, componentDetails } = this.state;
    return (
      <div className="parent">
        <h5>正确示例 1</h5>
        <p>父组件Count--{count}</p>
        <button onClick={this.handleClick}>增加</button>
        <Son componentDetails={componentDetails} anyMethod={this.anyMethod} />
      </div>
    );
  }
}

class Son extends PureComponent {
  constructor(props) {
    super(props);
  }
  render() {
    const { componentDetails, anyMethod } = this.props;
    console.log("Son -> render -> anyMethod", anyMethod);
    console.log("Son -> render -> componentDetails", componentDetails);
    return <div className="son">{componentDetails?.name}</div>;
  }
}

export default Parent;

✋🏻 点击查看在线 demo

本示例中,我们主要的正确写法就是直接将变量传递给子组件,因为变量的引用是相同的,因此经过PureComponent的检查,引用没有改变,从而阻止了子组件的渲染!!

说明: 严格来说,这个错误的示例是写法的问题,导致子组件的重新渲染,所以谈不上优化,因此我们要禁止像错误示例那样书写代码!

Hooks 示例

❎ 错误示例预览

2.HooksBad.gif

❎ 错误示例

import { useState, useEffect } from "react";
const Son = ({ componentDetails, anyMethod }) => {
  useEffect(() => {
    console.log("Son -> componentDetails", componentDetails);
  }, [componentDetails]);
  useEffect(() => {
    console.log("Son -> anyMethod", anyMethod);
  }, [anyMethod]);
  return <div className="son">{componentDetails.name}</div>;
};

const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>错误示例</h5>
      <p>父组件Count--{count}</p>
      <button onClick={handleClick}>增加</button>
      <Son componentDetails={{ name: "子组件" }} anyMethod={() => {}} />
    </div>
  );
};

export { Son, Parent };

✋🏻 点击查看在线 demo

在这个错误示例当中,还是传递props的写法问题!!接下来看看如何改正!

✅ 正确示例 1

import { useState, useEffect } from "react";
const Son = ({ componentDetails, anyMethod }) => {
  useEffect(() => {
    console.log("Son -> componentDetails", componentDetails);
  }, [componentDetails]);
  useEffect(() => {
    console.log("Son -> anyMethod", anyMethod);
  }, [anyMethod]);
  return <div className="son">{componentDetails.name}</div>;
};
// 这种写法 针对于 不变的值 可以这样传递
const componentDetails = { name: "子组件" };
const anyMethod = () => {};

const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };
  return (
    <div className="parent">
      <h5>正确示例1</h5>
      <p>父组件Count--{count}</p>
      <button onClick={handleClick}>增加</button>
      <Son componentDetails={componentDetails} anyMethod={anyMethod} />
    </div>
  );
};

export default Parent;

✋🏻 点击查看在线 demo

在这个示例中,我们只是将不变的值 提到组件之外 以保证引用的唯一,不会因为组件的更新而改变。但是这种写法有一定的局限性。就是只适合于不变的值。但也有效的避免了组件的重复渲染。

✅ 正确示例 2

import { useState, useEffect, useMemo, useCallback } from "react";
const Son = ({ componentDetails, anyMethod }) => {
  useEffect(() => {
    console.log("Son -> componentDetails", componentDetails);
  }, [componentDetails]);
  useEffect(() => {
    console.log("Son -> anyMethod", anyMethod);
  }, [anyMethod]);
  return <div className="son">{componentDetails.name}</div>;
};

const Parent = () => {
  const [count, setCount] = useState(0);
  const handleClick = () => {
    setCount((old) => old + 1);
  };

  const anyMethod = useCallback(() => {}, []);

  const [componentDetails] = useMemo(() => {
    const componentDetails = { name: "子组件" };
    return [componentDetails];
  }, []);

  return (
    <div className="parent">
      <h5>正确示例2</h5>
      <p>父组件Count--{count}</p>
      <button onClick={handleClick}>增加</button>
      <Son componentDetails={componentDetails} anyMethod={anyMethod} />
    </div>
  );
};

export default Parent;

✋🏻 点击查看在线 demo

在这个示例中,使用了 useCallbackuseMemo 这个两个优化Hook,主要就是根据依赖是否改变来确定是否要更新值的变化,以保证值的引用不变。这中写法适合于大部分的写法,但是也不能过度使用。要不然代码会很混乱。

Context的更新导致组件渲染

Class 示例

❎ 错误示例预览

3.ClassBad.gif

❎ 错误示例

import React, { Component, createContext } from "react";

const contextValue = createContext(undefined);

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      handleIncrement:this.handleIncrement
    };
  }
  handleIncrement = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };

  render() {


    return (
      <contextValue.Provider
        value={this.state}
      >
        <div className="parent">
          <h5>错误示例</h5>
          <Son1 />
          <contextValue.Consumer>
            {(conProps) => <Son2 conProps={conProps} />}
          </contextValue.Consumer>
        </div>
      </contextValue.Provider>
    );
  }
}

class Son1 extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("子组件 1 重新渲染了!!");
    return <div className="son">子组件 1</div>;
  }
}

class Son2 extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("子组件 2 重新渲染了!!");

    const {
      conProps: { count, handleIncrement },
    } = this.props;
    return (
      <div className="son">
        <p>子组件 2--{count}</p>
        <button onClick={handleIncrement}>增加</button>
      </div>
    );
  }
}

export { Parent };

✋🏻 点击查看在线 demo

在这个例子当中,仔细体会,当点击子组件2中的按钮时,改变的是父组件中的state 所以造成的问题就是 父组件的渲染导致子组件也渲染了。那应该怎样避免子组件的重复渲染呢?

✅ 正确示例 1

import React, { Component, createContext } from "react";

const contextValue = createContext(undefined);

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      handleIncrement:this.handleIncrement
    };
  }
  handleIncrement = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };

  render() {
    const { children } = this.props;
    return (
      <contextValue.Provider
        value={this.state}
      >
        <div className="parent">
          <h5>正确示例1</h5>
          {children}
          <contextValue.Consumer>
            {(conProps) => <Son2 conProps={conProps} />}
          </contextValue.Consumer>
        </div>
      </contextValue.Provider>
    );
  }
}

class Son1 extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("子组件 1 重新渲染了!!");
    return <div className="son">子组件 1</div>;
  }
}

class Son2 extends Component {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("子组件 2 重新渲染了!!");

    const {
      conProps: { count, handleIncrement },
    } = this.props;
    return (
      <div className="son">
        <p>子组件 2--{count}</p>
        <button onClick={handleIncrement}>增加</button>
      </div>
    );
  }
}

export { Parent, Son1 };

<Parent>
 <Son1 />
</Parent>

✋🏻 点击查看在线 demo

在这个示例中,我们还是借用了children 的机制,直接渲染,那么在父组件当中就没有 Ract.createElement(Son) 这个api的执行,因此就不会造成重复的渲染!

✅ 正确示例 2

import React, { Component, createContext, PureComponent } from "react";

const contextValue = createContext(undefined);

class Parent extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
      handleIncrement:this.handleIncrement
    };
  }
  handleIncrement = () => {
    const { count } = this.state;
    this.setState({
      count: count + 1,
    });
  };

  render() {
    return (
      <contextValue.Provider
        value={this.state}
      >
        <div className="parent">
          <h5>正确示例2</h5>
          <Son1 />
          <contextValue.Consumer>
            {(conProps) => <Son2 conProps={conProps} />}
          </contextValue.Consumer>
        </div>
      </contextValue.Provider>
    );
  }
}

class Son1 extends PureComponent {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("子组件 1 重新渲染了!!");
    return <div className="son">子组件 1</div>;
  }
}

class Son2 extends PureComponent {
  constructor(props) {
    super(props);
  }
  render() {
    console.log("子组件 2 重新渲染了!!");

    const {
      conProps: { count, handleIncrement },
    } = this.props;
    return (
      <div className="son">
        <p>子组件 2--{count}</p>
        <button onClick={handleIncrement}>增加</button>
      </div>
    );
  }
}

export default Parent;

✋🏻 点击查看在线 demo

在本示例中,主要是借用了 PureComponent 这个类帮我们自动执行优化,因此也是可以避免重复的渲染。

说明:这里你也可以强行使用一下React.memo。

Hooks 示例

❎ 错误示例预览

3.HooksBad.gif

❎ 错误示例

import { createContext, useContext } from "react";
import { useCustomReducer } from "../useCustomizeContext";
const CustomizeContext = createContext(undefined);

const Son1 = () => {
  console.log("子组件1 重新渲染了!!");
  return <div className="son">子组件1</div>;
};
const Son2 = () => {
  const { count, handleIncrement } = useContext(CustomizeContext);
  console.log("子组件2 重新渲染了!!");
  return (
    <div className="son">
      <p>子组件2-{count}</p>
      <button onClick={handleIncrement}>增加</button>
    </div>
  );
};

const Parent = () => {
  const value = useCustomReducer({ initValue: 1 });
  return (
    <CustomizeContext.Provider value={value}>
      <div className="parent">
        <h5>错误示例</h5>
        <Son2 />
        <Son1 />
      </div>
    </CustomizeContext.Provider>
  );
};

export { Son1, Parent, Son2 };

✋🏻 点击查看在线 demo

在本示例中 使用了createContext,useContext,useReducer 这几个api 实现了一个小型的Redux。再点击子组件2中的按钮,改变了count的值,进而导致 value 改变,因此父组件渲染,导致子组件也跟着渲染。

✅ 正确示例 1

import React from "react";
import {
  CustomizeProvider,
  useCustomizeContext,
  useCustomReducer,
} from "../useCustomizeContext";

const Son1 = () => {
  console.log("子组件1 重新渲染了!!");
  return <div className="son">子组件1</div>;
};
const Son2 = () => {
  const { count, handleIncrement } = useCustomizeContext();
  console.log("子组件2 重新渲染了!!");
  return (
    <div className="son">
      <p>子组件2-{count}</p>
      <button onClick={handleIncrement}>增加</button>
    </div>
  );
};

const Parent = ({ children }) => {
  const value = useCustomReducer({ initValue: 1 });
  return (
    <CustomizeProvider value={value}>
      <div className="parent">
        <h5>正确示例1</h5>
        <Son2 />
        {children}
      </div>
    </CustomizeProvider>
  );
};
export { Son1 };
export default Parent;


<Parent>
 <Son1 />
</Parent>

✋🏻 点击查看在线 demo

在本示例中我们依然是使用 children 来解决的重复渲染问题。这个方式还是很有效的!!

说明: 其实在项目中一定要使用合适的优化手段!

✅ 正确示例 2

import React, { memo } from "react";
import {
  CustomizeProvider,
  useCustomizeContext,
  useCustomReducer,
} from "../useCustomizeContext";

const Son1 = () => {
  console.log("子组件1 重新渲染了!!");
  return <div className="son">子组件1</div>;
};
const Son2 = () => {
  const { count, handleIncrement } = useCustomizeContext();
  console.log("子组件2 重新渲染了!!");
  return (
    <div className="son">
      <p>子组件2-{count}</p>
      <button onClick={handleIncrement}>增加</button>
    </div>
  );
};
// 使用 memo
const MemoSon1 = memo(Son1);
const Parent = () => {
  const value = useCustomReducer({ initValue: 1 });
  return (
    <CustomizeProvider value={value}>
      <div className="parent">
        <h5>正确示例2</h5>
        <Son2 />
        <MemoSon1 />
      </div>
    </CustomizeProvider>
  );
};

export default Parent;

✋🏻 点击查看在线 demo

在本示例中也使用了 memo 这个api, 还是一样的,对比props的引用是否改变,决定是否更新。

✅ 正确示例 3

import React, { useMemo } from "react";
import {
  CustomizeProvider,
  useCustomizeContext,
  useCustomReducer,
} from "../useCustomizeContext";

const Son1 = () => {
  console.log("子组件1 重新渲染了!!");
  return <div className="son">子组件1</div>;
};
const Son2 = () => {
  const { count, handleIncrement } = useCustomizeContext();
  console.log("子组件2 重新渲染了!!");
  return (
    <div className="son">
      <p>子组件2-{count}</p>
      <button onClick={handleIncrement}>增加</button>
    </div>
  );
};

const Parent = () => {
  const value = useCustomReducer({ initValue: 1 });
  return (
    <CustomizeProvider value={value}>
      <div className="parent">
        <h5>正确示例3</h5>
        <Son2 />
        {useMemo(
          () => (
            <Son1 />
          ),
          []
        )}
      </div>
    </CustomizeProvider>
  );
};

export default Parent;

✋🏻 点击查看在线 demo

在这个示例中我们依然借助useMemo 这个优化Hook, 来进行对组件的优化。

🤙🤙🤙 总结

在本片文章中介绍了三种情况下的优化手段,主要就是使用了:

  • 🤙useMemo
  • 🤙memo
  • 🤙children
  • 🤙useCallback
  • 🤙PureComponent
  • 🤙提取状态组件
  • 🤙提取不变的值

这些优化的手段可以在不同的情况使用,所以你如果在使用过程中,一定要结合代码的情况,使用合适的优化手段。

如果你还知道别的优化手段也可以在评论区进行留言哦!!!

👏👏👏 往期精彩