日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

[心得] 如何提高 React App 的性能

 就這樣了__ 2016-09-11


這篇是我最近在研究React.js時(shí)的一些心得,關(guān)于怎么使用 shouldComponentUpdate 及 immutable.js 提高性能。

Virtual DOM

因?yàn)槭褂脗鹘y(tǒng)的方式對(duì)DOM 進(jìn)行操作會(huì)很慢,為此React 設(shè)計(jì)了 Virtual DOM 這個(gè)中間層來(lái)降低操作 DOM 的成本。


Virtual DOM 是一個(gè)類似實(shí)際 DOM 節(jié)點(diǎn)的樹狀結(jié)構(gòu),當(dāng)有數(shù)據(jù)改變時(shí)才會(huì)透過(guò) diff 算法計(jì)算最小差異并更新到實(shí)際的 DOM 上。


所以當(dāng)我們 render 時(shí),其實(shí)都是 render 到 Virtual DOM 上,React 會(huì)自己幫我們算出最小差異然后更新。


shouldComponentUpdate

在講 shouldComponentUpdate 之前,先來(lái)看看 Component 的生命周期。當(dāng) state 或是 props 改變的時(shí)候,會(huì)先呼叫 shouldComponentUpdate(),如果回傳 true 才會(huì) render 到Virtual DOM,最后再由React 的 diff 算法決定要怎么更新 Real DOM。


因?yàn)?nbsp;shouldComponentUpdate() 預(yù)設(shè)是回傳 true,也就是 “一律重繪”,所以不管有沒有改變,一律重新 render到Virtual DOM 上,最后由 diff 算法判斷到底哪些需要改變。


雖然 React 的 diff 算法很高效,但如果數(shù)量一多,React 要遞歸跑完所有component 的 render,還是會(huì)拖慢速度,所以可以自己實(shí)現(xiàn)shouldComponentUpdate,如果數(shù)據(jù)相同就不要重新 render。


定義一個(gè)命叫 Item的Component:

// <Item content='item1' />
var Item = React.createClass({    render(){
       return <h1> {this.props.content} </h1>;    } });

可以加入一個(gè)shouldComponentUpdate(nextProps, nextState):

shouldComponentUpdate(nextProps, nextState){
   if(this.props.content !== nextProps.content) return true;
   return false; }

只有在this.props.content改變的時(shí)候才重新 render,這樣就可以大大減少重新render 的次數(shù)。

可能會(huì)遇到什么問(wèn)題?

可能會(huì)遇到props是對(duì)象或者數(shù)組的情況,但對(duì)象跟數(shù)組沒辦法比較相等,看看下面的例子:

var obj1 = {name: 'Larry', age: 19};
var obj2 = {name: 'Larry', age: 19};

console.log(obj1 === obj2);//false
console.log(obj1.name === obj2.name && obj1.age === obj2.age);//true

var
arr1 = [1, 2, 3];
var arr2 = [1, 2, 3];

console.log(arr1 === arr2);//false

// 比較 array 內(nèi)所有元素 -> true
console.log(function(){
   if(arr1.length != arr2.length) return false;
   for(var i=0 ; i<arr1.length ; i ){
       if(arr1[i] !== arr2[i]) return false;    }
   return true; }());

用===只能比較是不是同一個(gè)對(duì)象,如果要比較內(nèi)容的話要自己進(jìn)行比較,數(shù)組也是要自己遍歷整個(gè)數(shù)組,所以shouldComponentUpdate可能會(huì)寫成這樣:

// <List items={['item1', 'item2', 'item3']} />

shouldComponentUpdate(nextProps, nextState){
   if(this.props.items.length != nextProps.items.length) return true;
   for(var i=0 ; i<this.props.items.length ; i ){
       if(this.props.items[i] !== nextProps.items[i]) return true;    }
   return false; }

但因?yàn)槭潜闅v整個(gè)數(shù)組,如果數(shù)量一多的話還是會(huì)很慢,這時(shí)候就可以用immutable.js加速。

Immutable.js

immutable.js 是由Facebook 開源的一個(gè) library,提供各種不同的結(jié)構(gòu),可以用npm install immutable安裝。


比較常用的有 List 跟 Map,immutable.js 中的 List 就像是 Array

var Immutable = require('immutable');
var list1 = Immutable.List.of('a', 'b', 'c');
// ['a', 'b', 'c']
var list2 = Immutable.List.of('a', 'b', 'c');
// ['a', 'b', 'c']

console.log(Immutable.is(list1, list2));
// true
console.log(list1.get(0));
// 'a'
list1 = list1.set(0, 'b');
// list1 = ['b', 'b', 'c']
console.log(Immutable.is(list1, list2));
// false

immutable.js 中的 Map 就像是Object

var map1 = Immutable.Map({name: 'Larry', age: 19});
var map2 = Immutable.Map({name: 'Larry', age: 19});

console.log(Immutable.is(map1, map2));
// true
map1 = map1.set('name', 'Larry Lu');
// map1 = {name:'Larry Lu', age:19}

console.log(map1.get('name'));
// 'Larry Lu'
conosle.log(Immutable.is(map1, map2));
// false

這樣就可以用Immutable.js來(lái)比較數(shù)組跟對(duì)象,而且Immutable.js不是把每個(gè)值都取出來(lái)比較,而是在創(chuàng)建 List 跟 Map 時(shí)就計(jì)算得到一個(gè) hashvalue,比較時(shí)就比較那個(gè) hashvalue,所以速度會(huì)快非常多。


還有一個(gè)要注意的點(diǎn),immutable.js創(chuàng)造出來(lái)的對(duì)象是不可變的,在 js 內(nèi)要更改數(shù)組內(nèi)的元素只要使arr[index] = value,但用immutable.js時(shí)要使list = list.set(index,value)。因?yàn)閟et時(shí)不會(huì)更改原本的而是創(chuàng)造一個(gè)新的List,map也是一樣,所以一定要使map = map.set('name','Larry Lu')。

結(jié)論

綜合shouldComponentUpdate 及 Immutable.js 之后,最后就可以把 component 寫成這樣:

// <Item info={Immutable.Map({'name': 'Larry', age: 19})} />

var Item = React.createClass({    shouldComponentUpdate(nextProps, nextState){
       return !Immutable.is(this.props.info, nextProps.info);    },    render(){
       return (
           <div>                <h1> {'name: ' this.props.name} </h1>                <h2> {'age: ' this.props.age} </h2>            </div>        );    } });

這樣就可以減少重新 render 的次數(shù),而且在判斷要不要重新 render 時(shí)也可以非??焖?,讓原本就很快的 React 變得更快。


【React啟蒙系列文章】

一、[React啟蒙系列] 初探React

二、[React啟蒙系列] 學(xué)習(xí)React前需要理解的名詞

三、[React啟蒙系列] React和Babel的基本使用


【您可能感興趣的文章】

一、手把手教你用react

二、React入門及資源指引

三、利用ESLint檢查代碼質(zhì)量

四、構(gòu)建一個(gè)安全的 JavaScript 沙箱

五、入門Webpack,看這篇就夠了

六、第三屆CSS大會(huì)廣州找場(chǎng)地啦~~求介紹~~

七、Web Components 是個(gè)什么樣的東西

八、JavaScript 被忽視的細(xì)節(jié)



前端圈--打造專業(yè)的前端技術(shù)會(huì)議

為web前端開發(fā)者提供技術(shù)分享和交流的平臺(tái)

打造一個(gè)良好的前端圈生態(tài),推動(dòng)web標(biāo)準(zhǔn)化的發(fā)展

官網(wǎng):http://

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多