1.shouldComponentUpdate
成都創(chuàng)新互聯(lián)從2013年創(chuàng)立,先為呂梁等服務(wù)建站,呂梁等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為呂梁企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。一個(gè)組件更新時(shí),無論是設(shè)置了新的props/調(diào)用了setState方法/調(diào)用forceUpdate方法,React都會(huì)調(diào)用該組件所有子組件的render方法。在組件樹深度嵌套或render方法十分復(fù)雜的頁面上這可能會(huì)帶來延遲。
組件的render方法有時(shí)候會(huì)在不必要的情況下被調(diào)用。如:在組件渲染過程中沒有使用props或state值,或組件的props或state并沒有在父組件重新渲染時(shí)發(fā)生改變時(shí),重新渲染這個(gè)組件會(huì)得到和已存在的虛擬DOM結(jié)構(gòu)一模一樣的結(jié)構(gòu),這樣的設(shè)計(jì)過程是沒有必要的。
React提供的組件生命周期方法:shouldComponentUpdate可以幫助React正確地判斷是否需要調(diào)用指定組件的render方法。
shouldComponentUpdate返回false即可以不調(diào)用組件的渲染方法,并使用之前渲染好的虛擬DOM;返回true則是讓React調(diào)用組件的渲染方法并計(jì)算出新的虛擬DOM。默認(rèn)返回true,因此組件總是會(huì)調(diào)用render方法。
在組件首次渲染時(shí),shouldComponentUpdate方法不會(huì)被調(diào)用。
shouldComponentUpdate方法接收兩個(gè)參數(shù),即新的props和新的state,以幫助你決定是否重新渲染:
var SurveyEditor = React.createClass({
shouldComponentUpdate:function (nextProps, nextState) {
return nextProps.id !== this.props.id;
}
});
對(duì)于給定同樣的props和state總是渲染出同樣結(jié)果的組件,我們可以添加React.addons.PureRenderMixin插件來處理shouldComponentUpdate。
這個(gè)插件會(huì)重寫shouldComponentUpdate方法,并在該方法內(nèi)對(duì)新老props及state進(jìn)行對(duì)比,如果發(fā)現(xiàn)它們完全一致則返回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結(jié)構(gòu)較深或較復(fù)雜,對(duì)比的過程會(huì)比較緩慢。為減少這種情況帶來的問題,可以考慮使用不可變的數(shù)據(jù)結(jié)構(gòu),比如:Immutable.js,或使用不可變性輔助插件。
2.不可變性輔助插件
在需要比較對(duì)象以確認(rèn)是否更新時(shí),使用不可變的數(shù)據(jù)結(jié)構(gòu)能讓shouldComponentUpdate方法變得更加簡(jiǎn)單。
可以使用React.addons.update來確保組件的不可變性。React.addons.update接受一個(gè)數(shù)據(jù)結(jié)構(gòu)和一個(gè)配置對(duì)象。可以在配置對(duì)象中傳入$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.深入調(diào)查拖慢應(yīng)用的部分
React.addons.Perf插件能找到添加shouldComponentUpdate的最佳位置。
首先在Chrome控制臺(tái)中運(yùn)行React.addons.Perf.start();該命令會(huì)啟動(dòng)采集快照。
然后在頁面操作后運(yùn)行React.addons.Perf.stop();
最后再在控制臺(tái)運(yùn)行React.addons.Perf.printWaster();會(huì)輸出列表,列表中包含組件和組件耗費(fèi)時(shí)間。對(duì)于沒有改變props和state的組件可以設(shè)置shouldComponentUpdate:function(){return false;}
4.鍵(key)
列表中使用key屬性。作用:給React提供一種除組件類之外的識(shí)別子組件的最小變化。
項(xiàng)目地址:https://github.com/backstopmedia/bleeding-edge-sample-app
參考書:《React引領(lǐng)未來的用戶界面開發(fā)框架》
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。
網(wǎng)頁名稱:React性能優(yōu)化-創(chuàng)新互聯(lián)
分享路徑:http://muchs.cn/article30/cdjppo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、品牌網(wǎng)站建設(shè)、動(dòng)態(tài)網(wǎng)站、搜索引擎優(yōu)化、關(guān)鍵詞優(yōu)化、云服務(wù)器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容
移動(dòng)網(wǎng)站建設(shè)知識(shí)