react 组件性能优化

如果你并非在做大型而复杂的应用, 你不需要过早地进行性能优化, 还是先把应用做出来吧

react性能优化

class组件优化
1.shouldComponentUpdate
比较组件的props和state是否真的发生变化,如果发生变化则返回true,否则返回false。引用官网的案例。

class CounterButton extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 1};
  }

  shouldComponentUpdate(nextProps, nextState) {
    if (this.props.color !== nextProps.color) {
      return true;
    }
    if (this.state.count !== nextState.count) {
      return true;
    }
    return false;
  }

  render() {
    return (
      <button
        color={this.props.color}
        onClick={() => this.setState(state => ({count: state.count + 1}))}>
        Count: {this.state.count}
      </button>
    );
  }
}

2.PureComponent (PureRender是浅比较的,因为深比较的场景是相当昂贵的。所以不要直接为props设置对象或者数组、不要将方法直接绑定在元素上,因为其实函数也是对象)

handleClick() {
  this.setState(prevState => ({
    words: [...prevState.words, 'marklar'],
  }));
};

function updateColorMap(colormap) {
  return {...colormap, right: 'blue'};
}

3.Immutable(通过Immutable创建的Immutable Data一旦被创建,就不能再更改。对Immutable对象进行修改、添加或删除操作,都会返回一个新的Immutable对象。
immutable 内部使用了 Trie 数据结构来存储,只要两个对象的 hashCode 相等,值就是一样的。这样的算法避免了深度遍历比较,性能非常好。)

const SomeRecord = Immutable.Record({ foo: null });
const x = new SomeRecord({ foo: 'bar' });
const y = x.set('foo', 'baz');
x === y; // false

4.hooks
5.多个react组件性能优化,key的优化;
key属性在组件类之外提供了另一种方式的组件标识。通过key标识,在组件发生增删改、排序等操作时,可以根据key值的位置直接调整DOM顺序,告诉React 避免不必要的渲染而避免性能的浪费。
例,对于一个基于排序的组件渲染:

var items = sortBy(this.state.sortingAlgorithm, this.props.items);
return items.map(function(item){
  return <img src={item.src} />
});

当顺序发生改变时,React 会对元素进行diff操作,并改img的src属性。显示,这样的操作效率是非常低的。这时,我们可以为组件添加一个key属性以唯一的标识组件:

return <img src={item.src} key={item.id} />

增加key后,React就不是diff,而是直接使用insertBefore操作移动组件位置,而这个操作是移动DOM节点最高效的办法。

6.bind函数
绑定this的方式:一般有下面3种方式:
1、constructor绑定

constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this); //构造函数中绑定
}

//然后可以
<p onClick={this.handleClick}>

2、使用时绑定

<p onClick={this.handleClick.bind(this)}>

3、使用箭头函数

<Test click={() => { this.handleClick() }}/>

以上三种方法,第一种最优。
因为第一种构造函数只在组件初始化的时候执行一次,
第二种组件每次render都会执行
第三种在每一次render时候都会生成新的箭头函数。例:Test组件的click属性是个箭头函数,组件重新渲染的时候Test组件就会因为这个新生成的箭头函数而进行更新,从而产生Test组件的不必要渲染。

7.不要滥用props
props尽量只传需要的数据,避免多余的更新,尽量避免使用{…props}

8.不要用{{}}方式直接定义object,而是用一个变量进行缓存。
举个例子:
当我们给组件Foo给名为style的prop赋值;
<Foo style={{ color:“red” }}
使用这种方法,每一次渲染都会被认为是一个style这个prop发生了变化,因为每一次都会产生一个对象给style。

const fooStyle = { color: “red” }; //取保这个初始化只执行一次,不要放在render中,可以放在构造函数中

这个问题是我们在平时的编码中可以避免的。

8.react性能检测工具

hooks

  1. useMemo 优化
    每个函数体当中生成的对象都会有新的引用, useMemo 可以保留一致的引用.
const myObject = useMemo(() => ({ key: "value" }), [])
  1. React.memo 优化
    判断参数是否改变, 如果没有改变, 就直接复用已有的组件, 不重新生成
//React.memo 有第二个参数, 用于自定义判断的规则:
const MyComponent = React.memo(function MyComponent(props) {
  /* only rerenders if props change */
  
});
  1. useCallback 优化
let Inner: FC<{
  onClick: () => void
}> = React.memo((props) => {
  return <div>
    <span>inner</span>
    </div>;
});
// onClick函数也是一种引用,如果是箭头函数每次都会重新生成新的对象
let Outer: FC<{}> = React.memo((props) => {
  const [counter, setCounter] = useState(0);
  const onClick = useCallback(()=>{ 
    setCounter(prevState => ++prevState)
  },[]);
  return <div>
    <span>outer: {counter}</span>
    <Inner onClick={onClick} />
  </div>;
});
  1. useRef 优化
    useRef 返回一个可变的 ref 对象,其 .current 属性被初始化为传入的参数(initialValue)。返回的 ref 对象在组件的整个生命周期内保持不变。
function TextInputWithFocusButton() {
  const inputEl = useRef(null);
  const onButtonClick = () => {
    // `current` 指向已挂载到 DOM 上的文本输入元素
    inputEl.current.focus();
  };
  return (
    <>
      <input ref={inputEl} type="text" />
      <button onClick={onButtonClick}>Focus the input</button>
    </>
  );
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值