美文网首页
React性能优化

React性能优化

作者: 肾仔博 | 来源:发表于2020-12-24 08:47 被阅读0次

    1、keys的优化

    \triangleright 1.key应该要唯一;
    \triangleright 2.key不要使用随机数;
    \triangleright 3.使用index作为key,对性能并没有优化;

    <ul>
    {
        this.state.movies.map((item, index) => {
           return <li key={item}>{item}</li>
        })
    }
    </ul>
    

    2、shouldComponentUpdate

    React提供了一个生命周期方法shouldComponentUpdate(),这个方法能够控制render方法的调用,它接收参数,并且需要有返回值。

    • 该方法有两个参数:
      \triangleright nextProps:修改后,最新的props属性;
      \triangleright nextState:修改后,最新的state属性;
    • 该方法返回值是一个boolean类型
      \triangleright 返回值为:true,则需要调用render方法;
      \triangleright 返回值为:false,则不需要调用render方法;
      \triangleright 默认值返回的是true,只要state发生改变,则会调用render方法;
        shouldComponentUpdate(nextProps, nextState) {
            if (this.state.counter !== nextState.counter) {
                return true;
            }
            return false;
        }
    

    3、PureComponent

    PureComponent就是检测类组件中的state和props是否有发生变化,若发生改变则决定重新渲染组件。
    用法:class App extends PureComponent{} (使用类组件都最好用PureComponent包裹)

    • PureComponent在shouldeComponentUpdate里,下面的代码就是shouldComponentUpdate的一部分源码
    if  (ctor.prototype  &&  ctor.proptype.isPureReactComponent){
          return (
           !shallowEqual(oldProps,newProps)  ||  
           !shallowEqual(oldState,newState)
        );
    }
    

    shallowEqual这个方法就是进行一个浅层比较;

    • 什么是浅层比较????

    在js中的===是做浅层比较,它会检查两边的数值是否为同一个对象的引用,若相同则为true,否则为false;

    • JavaScript中的==和===的区别

    因为JS是弱类型语言,如果两个数值用==进行比较的话,==操作符会自动将0,' '(空字符串),null,undefined转为布尔类型;
    因此代码会出现:

    0 == ' '  //true
    null == undefined  //true
    [1] == true  //true
    

    所以JS提供了全等操作符===,它要求===两边的类型和数值都必须一样,这才能返回true,但是它疏忽了两种情况:

    +0 === -0  //true,但我们期待它返回false
    NaN === NaN  //false,但我们期待它返回true
    
    • 这个时候就需要用Object.is()方法
      function (x,y)  {
          if(x  ===  y){
              //处理+0===-0的情况
            return x !== 0 || 1/x === 1/y;
      }else{
              //处理NaN===NaN的情况
            return x !== x && y !== y;
          }
      }
    
    Object.is()方法

    解析shallowEqual的代码:

    // 用原型链的方法
    const hasOwn = Object.prototype.hasOwnProperty
    
    // 这个函数实际上是Object.is()的polyfill
    function is(x, y) {
      if (x === y) {
        return x !== 0 || y !== 0 || 1 / x === 1 / y
      } else {
        return x !== x && y !== y
      }
    }
    
    export default function shallowEqual(objA, objB) {
      // 首先对基本数据类型的比较
      if (is(objA, objB)) return true
      // 由于Obejct.is()可以对基本数据类型做一个精确的比较, 所以如果不等
      // 只有一种情况是误判的,那就是object,所以在判断两个对象都不是object
      // 之后,就可以返回false了
      if (typeof objA !== 'object' || objA === null ||
          typeof objB !== 'object' || objB === null) {
        return false
      }
    
      // 过滤掉基本数据类型之后,就是对对象的比较了
      // 首先拿出key值,对key的长度进行对比
    
      const keysA = Object.keys(objA)
      const keysB = Object.keys(objB)
    
      // 长度不等直接返回false
      if (keysA.length !== keysB.length) return false
      // key相等的情况下,在去循环比较
      for (let i = 0; i < keysA.length; i++) {
      // key值相等的时候
      // 借用原型链上真正的 hasOwnProperty 方法,判断ObjB里面是否有A的key的key值
      // 属性的顺序不影响结果也就是{name:'daisy', age:'24'} 跟{age:'24',name:'daisy' }是一样的
      // 最后,对对象的value进行一个基本数据类型的比较,返回结果
        if (!hasOwn.call(objB, keysA[i]) ||
            !is(objA[keysA[i]], objB[keysA[i]])) {
          return false
        }
      }
    
      return true
    }
    
    • 注意:shallowEqual中的浅层比较仅用了Object.is()方法对数据进行了基本数据的比较,若数据是对象的话,可能会出现不符合预期的情况,因此浅层比较不适用于嵌套类型的比较!!

    4、memo(高阶组件)

    memo()能让函数式组件提升性能

    const MemoText = memo(function fn(){
     }) 
    

    参考资料:https://cloud.tencent.com/developer/article/1015733

    相关文章

      网友评论

          本文标题:React性能优化

          本文链接:https://www.haomeiwen.com/subject/plhunktx.html