React性能优化-创新互联

1.shouldComponentUpdate

成都创新互联从2013年创立,先为吕梁等服务建站,吕梁等地企业,进行企业商务咨询服务。为吕梁企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

     一个组件更新时,无论是设置了新的props/调用了setState方法/调用forceUpdate方法,React都会调用该组件所有子组件的render方法。在组件树深度嵌套或render方法十分复杂的页面上这可能会带来延迟。

     组件的render方法有时候会在不必要的情况下被调用。如:在组件渲染过程中没有使用props或state值,或组件的props或state并没有在父组件重新渲染时发生改变时,重新渲染这个组件会得到和已存在的虚拟DOM结构一模一样的结构,这样的设计过程是没有必要的。

     React提供的组件生命周期方法:shouldComponentUpdate可以帮助React正确地判断是否需要调用指定组件的render方法。

      shouldComponentUpdate返回false即可以不调用组件的渲染方法,并使用之前渲染好的虚拟DOM;返回true则是让React调用组件的渲染方法并计算出新的虚拟DOM。默认返回true,因此组件总是会调用render方法。

     在组件首次渲染时,shouldComponentUpdate方法不会被调用。

      shouldComponentUpdate方法接收两个参数,即新的props和新的state,以帮助你决定是否重新渲染:

var SurveyEditor = React.createClass({

   shouldComponentUpdate:function (nextProps, nextState) {

      return nextProps.id !== this.props.id;

   }

});

     对于给定同样的props和state总是渲染出同样结果的组件,我们可以添加React.addons.PureRenderMixin插件来处理shouldComponentUpdate。

     这个插件会重写shouldComponentUpdate方法,并在该方法内对新老props及state进行对比,如果发现它们完全一致则返回false,如上面的例子。

var EditEssayQuestion = React.createClass({

   mixin: [React.addons.PureRenderMixin],

   propTypes: {

      key: React.PropTypes.number.isRequired,

      onChange: React.PropTypes.func.isRequired,

      onRemove: React.PropTypes.func.isRequired,

      question: React.PropTypes.object.isRequired

   },

   render: function () {

      var description = this.props.question.description || "";

      return (

         <EditQuestion type='essay' onRemove={this.handleRemove}>

            <label>Description</label>

            <input type='text' className='description' value={description} onChange={this.handleChange} />

         </EditQuestion>

      );

   },

   handleChange: function (ev) {

      var question = merge(this.props.question, { description: ev.target.value });

      this.props.onChange(this.props.key, question);

   },

   handleRemove: function () {

      this.props.onRemove(this.props.key);

   }

});

     如果props或state结构较深或较复杂,对比的过程会比较缓慢。为减少这种情况带来的问题,可以考虑使用不可变的数据结构,比如:Immutable.js,或使用不可变性辅助插件。

  2.不可变性辅助插件

     在需要比较对象以确认是否更新时,使用不可变的数据结构能让shouldComponentUpdate方法变得更加简单。

     可以使用React.addons.update来确保组件的不可变性。React.addons.update接受一个数据结构和一个配置对象。可以在配置对象中传入$slice、$push、$unshift、$set、$merge和$apply。

var React = require('react/addons');

var Divider = require('./divider');

var DraggableQuestions = require('./draggable_questions');

var SurveyForm = require('./survey_form');

var EditYesNoQuestion = require('./questions/edit_yes_no_question');

var EditMultipleChoiceQuestion = require('./questions/edit_multiple_choice_question');

var EditEssayQuestion = require('./questions/edit_essay_question');

var SurveyActions = require("../flux/SurveyActions");

var update = React.addons.update;

var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;

var SUPPORTED_QUESTIONS = {

   yes_no: EditYesNoQuestion,

   multiple_choice: EditMultipleChoiceQuestion,

   essay: EditEssayQuestion

};

var SurveyEditor = React.createClass({

   getInitialState: function () {

   return {

      dropZoneEntered: false,

      title: '',

      introduction: '',

      questions: []

   };

},

   render: function () {

      var questions = this.state.questions.map(function (q, i) {

         return SUPPORTED_QUESTIONS[q.type]({

            key: i,

            onChange: this.handleQuestionChange,

            onRemove: this.handleQuestionRemove,

            question: q

         });

      }.bind(this));

   var dropZoneEntered = '';

   if (this.state.dropZoneEntered) {

      dropZoneEntered = 'drag-enter';

   }

      return (

         <div className='survey-editor'>

            <div className='row'>

               <aside className='sidebar col-md-3'>

                  <h3>Modules</h3>

                  <DraggableQuestions />

               </aside>

               <div className='survey-canvas col-md-9'>

                  <SurveyForm

                     title={this.state.title}

                     introduction={this.state.introduction}

                     onChange={this.handleFormChange}

                  />

                  <Divider>Questions</Divider>

                  <ReactCSSTransitionGroup transitionName='question'>

                     {questions}

                  </ReactCSSTransitionGroup>

                  <div

                     className={'drop-zone well well-drop-zone ' + dropZoneEntered}

                     onDragOver={this.handleDragOver}

                     onDragEnter={this.handleDragEnter}

                     onDragLeave={this.handleDragLeave}

                     onDrop={this.handleDrop}

                  >

                     Drag and drop a module from the left

                  </div>

                  <div className='actions'>

                     <button className="btn btn-lg btn-primary btn-save" onClick={this.handleSaveClicked}>Save</button>

                  </div>

               </div>

            </div>

         </div>

      );

   },

   handleFormChange: function (formData) {

      this.setState(formData);

   },

   handleDragOver: function (ev) {

      // This allows handleDropZoneDrop to be called

      // https://code.google.com/p/chromium/issues/detail?id=168387

      ev.preventDefault();

   },

   handleDragEnter: function () {

      this.setState({dropZoneEntered: true});

   },

   handleDragLeave: function () {

      this.setState({dropZoneEntered: false});

   },

   handleDrop: function (ev) {

      var questionType = ev.dataTransfer.getData('questionType');

      var questions = update(this.state.questions, {

         $push: [{ type: questionType }]

      });

      this.setState({

         questions: questions,

         dropZoneEntered: false

      });

   },

   handleQuestionChange: function (key, newQuestion) {

      var questions = update(this.state.questions, {

         $splice: [[key, 1, newQuestion]]

      });

      this.setState({ questions: questions });

   },

   handleQuestionRemove: function (key) {

      var questions = update(this.state.questions, {

         $splice: [[key, 1]]

      });

      this.setState({ questions: questions });

   },

   handleSaveClicked: function (ev) {

      SurveyActions.save({

         title: this.state.title,

         introduction: this.state.introduction,

         questions: this.state.questions

      });

   }

});

  3.深入调查拖慢应用的部分

     React.addons.Perf插件能找到添加shouldComponentUpdate的最佳位置。

     首先在Chrome控制台中运行React.addons.Perf.start();该命令会启动采集快照。

     然后在页面操作后运行React.addons.Perf.stop();

     最后再在控制台运行React.addons.Perf.printWaster();会输出列表,列表中包含组件和组件耗费时间。对于没有改变props和state的组件可以设置shouldComponentUpdate:function(){return false;}

   4.键(key)

     列表中使用key属性。作用:给React提供一种除组件类之外的识别子组件的最小变化。

项目地址:https://github.com/backstopmedia/bleeding-edge-sample-app

参考书:《React引领未来的用户界面开发框架》

另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。

网页名称:React性能优化-创新互联
分享路径:/article30/cdjppo.html

成都网站建设公司_创新互联,为您提供全网营销推广品牌网站建设动态网站搜索引擎优化关键词优化云服务器

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

成都网页设计公司