React性能優化

1.shouldComponentUpdate

城中ssl適用于網站、小程序/APP、API接口等需要進行數據傳輸應用場景,ssl證書未來市場廣闊!成為創新互聯建站的ssl證書銷售渠道,可以享受市場價格4-6折優惠!如果有意向歡迎電話聯系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!

        一個組件更新時,無論是設置了新的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引領未來的用戶界面開發框架》

本文題目:React性能優化
本文網址:http://m.kartarina.com/article8/jecoip.html

成都網站建設公司_創新互聯,為您提供建站公司網站改版網站建設網站制作軟件開發網站內鏈

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

綿陽服務器托管
主站蜘蛛池模板: 成人免费无码大片A毛片抽搐| 免费无码午夜福利片69| 国产成人无码免费视频97 | 亚洲AV无码一区二区三区人| 中文字幕久久久人妻无码| heyzo专区无码综合| 久久亚洲精品无码AV红樱桃 | 波多野结衣VA无码中文字幕电影| 一本大道无码日韩精品影视| 亚洲精品无码永久在线观看男男 | 一区二区无码免费视频网站| 亚洲?V无码成人精品区日韩 | 免费无码又爽又刺激网站直播| 精品无码综合一区二区三区 | 国产精品爽爽va在线观看无码| 一本一道AV无码中文字幕| 国产成人无码专区| AA区一区二区三无码精片| 中文字幕精品无码久久久久久3D日动漫| 精品无码AV无码免费专区| 中文字幕无码久久人妻| 在线观看无码的免费网站| 无码精品久久久久久人妻中字| 无码专区中文字幕无码| 亚洲AV无码专区亚洲AV伊甸园| 日韩精品无码一区二区视频| 亚洲AV成人无码网站| 免费A级毛片无码久久版| 日韩精品专区AV无码| 国产精品无码AV一区二区三区| 无码人妻精品一区二区三区夜夜嗨| 日韩AV无码精品一二三区| 亚洲欧洲AV无码专区| 无码成人精品区在线观看| 久久无码高潮喷水| 亚洲AV无码乱码麻豆精品国产| 日韩精品人妻系列无码专区| 亚洲大尺度无码无码专区| 亚洲第一极品精品无码久久| 午夜人性色福利无码视频在线观看| 亚洲国产精品成人精品无码区 |