React优化手段

1 优化原则

不要过早对项目进行优化
切勿浪费精力在对整体性能提高的不多的代码上
对于关键的性能点尽早优化

react使用虚拟dom树提高性能,每次渲染并非抛弃所有重新渲染,而是借助虚拟dom计算dom树的最小修改

优化点:在计算前就判定是否需要去重新渲染

2 常用手段

使用shouldComponentUpdate来判定是否需要重新渲染是最常用的手段

2.1 单个React组件优化

  1. 在构造函数中绑定this
    对于回调函数有三种方法进行绑定:构造中、render中、箭头函数,三种方法中只有构造函数是只执行一次的(箭头函数也可以)。尽量少在render中绑定回调,因为每次绑定,对于被绑定的组件来说,传入的回调函数都是一个新对象,都会造成子组件重新渲染。
// render中绑定回调,当父组件重新渲染时,子组件一定会重新渲染
...
render(){
  return <A onClick={()=>{console.log(1)}} />
}
...
  1. render中的参数尽量使用同一对象
    由于react判定是否需要重新渲染,是通过浅层比较(地址比较)来判断的,对于值类型的变量来说没什么问题,对于引用类型的来说需要确保每次都是传入的原来的对象,否则造成性能浪费,如:
<Foo style={{color: 'red'}} />

传入的是一个对象,而每次render时该对象都是一个新的对象,会被react认为Foo组件的props每次render均发生变化,建议使用:

const fooStyle = {color: 'red'}
<Foo style={fooStyle} />
  1. 列表数据使用单独组建进行渲染
    由于列表元素渲染非常耗时,即使列表元素未发生改变,react在比较新旧列表元素时依然需要花费大量时间,建议将列表元素包装为一个组件进行单独渲染
// 新旧比较花费大量时间
{x.map(item=><p>item</p>)}
// 包装成组件后
<X content={x}/>
const X = props => <div>{props.content.map(item=><p>item</p>)}</div>

2.2 shouldComponentUpdate解析

react默认每次更新都会调用所有的生命周期函数,所以如果没有重写该周期函数,默认是直接返回true

react渲染规则:
在这里插入图片描述
从React组件的根节点开始依次按照该规则进行检查

  1. 当前节点检查scu为true,则会进行vDOMEq比较,如果比较结果为一致就停止更新,否则向下进行遍历
  2. 当前节点检查scu为false,直接停止该节点更新

起始相当于双保险:一个是scu的true和false,另一个是vDOMEq的true和false,任一为false,都会让该节点不更新,只有两个都为true才会更新该节点

2.3 PureComponent

由于大多数情况下只需要对比state和props来判断是否需要更新,所以PureComponent类实现了自己的更新方法,自动的浅比较state和props来判断是否需要更新

特别注意:对于state或props中包含引用数据类型的无法判断是否被改变了!!
如:

import React, { PureComponent } from 'react'
class MyTest2 extends PureComponent {
  constructor(props) {
    super(props);
    this.state = {
      arr: []
    }
  }
  add1 = () => {
    let arr = this.state.arr
    arr.push(1)
    this.setState({ arr })
  }
  // shouldComponentUpdate() {

  // }
  render() {
    console.log('update')
    return (
      <div>{this.state.arr.length}<button onClick={this.add1}>click2</button></div>
    );
  }
}

export default MyTest2;

该组件单击后无任何变化,虽然state中的arr已经被改变了,但是页面不会被重新渲染

2.4 使用immutable(ImmutableJS)

待补充

3 其他优化点

  1. 慎用展开语法{...this.props},该语法会创建一个新对象,同时传递很多当前组件不需要的参数
  2. 在构造中进行函数this绑定
  3. 复杂页面尽量拆分
  4. 对于不变的展示组件使用const element
  5. map必须要添加key
  6. props和state尽量扁平化
  7. 使用return null来控制组件的显隐,而不是css的display:none
  8. 对于mobx+react来说,尽可能晚的解引用,能防止引用的属性变化导致父组件重渲染,进而自组建重渲染(由于mobx会观测当前组件可观测属性的变化,解引用早了,该引用变化会引起当前组件重渲染,并可能引起子组件重渲染)
// personStore中的name发生变化
// 早解引用
<A a={personStore.name}/>
// 晚解引用
<A a={personStore}/>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值