這篇是我最近在研究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 的成本。
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' /> 可以加入一個(gè)shouldComponentUpdate(nextProps, nextState): shouldComponentUpdate(nextProps, nextState){ 只有在this.props.content改變的時(shí)候才重新 render,這樣就可以大大減少重新render 的次數(shù)。 可能會(huì)遇到什么問(wèn)題?可能會(huì)遇到props是對(duì)象或者數(shù)組的情況,但對(duì)象跟數(shù)組沒辦法比較相等,看看下面的例子: var obj1 = {name: 'Larry', age: 19}; 用===只能比較是不是同一個(gè)對(duì)象,如果要比較內(nèi)容的話要自己進(jìn)行比較,數(shù)組也是要自己遍歷整個(gè)數(shù)組,所以shouldComponentUpdate可能會(huì)寫成這樣: // <List items={['item1', 'item2', 'item3']} /> 但因?yàn)槭潜闅v整個(gè)數(shù)組,如果數(shù)量一多的話還是會(huì)很慢,這時(shí)候就可以用immutable.js加速。 Immutable.jsimmutable.js 是由Facebook 開源的一個(gè) library,提供各種不同的結(jié)構(gòu),可以用npm install immutable安裝。
var Immutable = require('immutable'); immutable.js 中的 Map 就像是Object var map1 = Immutable.Map({name: 'Larry', age: 19}); 這樣就可以用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})} /> 這樣就可以減少重新 render 的次數(shù),而且在判斷要不要重新 render 時(shí)也可以非??焖?,讓原本就很快的 React 變得更快。 【React啟蒙系列文章】 二、[React啟蒙系列] 學(xué)習(xí)React前需要理解的名詞 三、[React啟蒙系列] React和Babel的基本使用 【您可能感興趣的文章】 四、構(gòu)建一個(gè)安全的 JavaScript 沙箱 六、第三屆CSS大會(huì)廣州找場(chǎng)地啦~~求介紹~~ 前端圈--打造專業(yè)的前端技術(shù)會(huì)議 為web前端開發(fā)者提供技術(shù)分享和交流的平臺(tái) 打造一個(gè)良好的前端圈生態(tài),推動(dòng)web標(biāo)準(zhǔn)化的發(fā)展 官網(wǎng):http:// |
|