美文网首页
4. React性能优化:避免组件更新

4. React性能优化:避免组件更新

作者: 萘小蒽 | 来源:发表于2020-08-20 08:34 被阅读0次

    首先需要了解的周期方法是ShouldComponentUpdate(nextProps,nextState),它对于构建性能关键型的应用场景尤为重要。它会在componentWillUpdate()之前触发。当非必须时可以取消组件更新。

    有一类组件在render()方法中只使用了this.state、this.props,而没有其他额外的函数调用。这一类组件被称为“纯组件”。我们可以在shouldComponentUpdate()中比较前后的状态与属性,如果没有发生任何变化,返回false,以节省部分处理能力。

     var Counter = React.createClass({
            name: 'Counter',
            propTypes: {
              count: React.PropTypes.number.isRequired,
            },
            
            render: function() {
              console.log(this.name + '::render()');
              return React.DOM.span(null, this.props.count);
            }
          });
    
          var TextAreaCounter = React.createClass({
            name: 'TextAreaCounter',
            
            // mixins: [logMixin],
    
            propTypes: {
              defaultValue: React.PropTypes.string,
            },
    
            getInitialState: function() {
              return {
                text: this.props.defaultValue,
              };
            },
    
            _textChange: function(ev) {
              this.setState({
                text: ev.target.value,
              });
            },
    
            render: function() {
              console.log(this.name + '::render()');
              var counter = null;
              if (this.state.text.length > 0) {
                counter = React.DOM.h3(null, 
                  React.createElement(Counter, {
                    count: this.state.text.length,
                  })
                );
              }
              return React.DOM.div(null,
                React.DOM.textarea({
                  value: this.state.text,
                  onChange: this._textChange,
                }),
                counter
              );
            }
          });
    
          var myTextAreaCounter = ReactDOM.render(
            React.createElement(TextAreaCounter, {
              defaultValue: "Bob",
            }),
            document.getElementById("app")
          );
    

    上面这个例子中,输入框内初始化为Bob,长度为3,当你复制长度为3的字符串在输入框中时,Counter组件中的长度并没有发生变化(依然为3),但是render却触发了。

    Counter组件中加入shouldComponentUpdate方法:

            shouldComponentUpdate: function(nextProps, nextState) {
              // console.log(this.name + '::shouldComponentUpdate()');
              return nextProps.count !== this.props.count;
            },
    

    PureRebderMixin
    上面的优化只需要对this.props和nextProps,以及this.state和nextState进行比较即可,对此React通过mixin的形式提供了一种通用现实,并且可以简单的应用与任何组件。

    var Counter = React.createClass({
            name: 'Counter',
            mixins: [React.addons.PureRenderMixin],
            propTypes: {
              count: React.PropTypes.number.isRequired,
            },
            render: function() {
              console.log(this.name + '::render()');
              return React.DOM.span(null, this.props.count);
            }
          });
    

    在0.14版本之后,React.addons 单独分离出来(与Babel 6类似),各自成为插件,需要单独加载。
    不希望完全引入全部插件,依靠自己实现:

    var ReactComponentWithPureRenderMixin = {
        shouldComponentUpdate: function(nextProps, nextState){
            return !shallowEqua(this.props,this.nextProps)||!shallowEqua(this.state,this.nextState);
        }
    }
    

    仅仅是对相等性进行浅层(非递归)检查

    function shallowEqual(objA, objB) {
        if(objA === objB) {
            return true;
        }
        var keyA = Object.keys(objA),
            keyB = Object.keys(objB);
    
        if(keyA.length != keyB.length) {
            return false;
        }
    
        for(var idx = 0, len = keyA.length; idx < len; idx++ ) {
            var key = keyA[idx];
            
            if(!objB.hasOwnProperty(key)) {
                return false;
            }
            var valueA = objA[key],
                  valueB = objB[key];
            // 无差别比较,引用类型比较引用,基础类型直接比较值
            if(valueA !== valueB) {
                return false;
            }
        }
        return true;
    }
    

    相关文章

      网友评论

          本文标题:4. React性能优化:避免组件更新

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