React組件優(yōu)化
? ? 1. 屬性傳遞優(yōu)化
在動(dòng)態(tài)頁面中,免不了使用事件來監(jiān)控按鈕,React中便針對(duì)這種情況有相應(yīng)的優(yōu)化。以點(diǎn)擊事件onClick為例,在React中,事件的聲明方式有三種
① 事件在聲明時(shí)一起綁定

② 使用函數(shù)式聲明事件:

③ 在按鈕內(nèi)聲明,在constructor內(nèi)綁定:

? ? ? ? ? 三種聲明方式的比較:①②相對(duì)于③,再次執(zhí)行時(shí)都要再渲染一編render()里的bind函數(shù)和函數(shù)聲明式,而③的綁定函數(shù)只執(zhí)行一次,并不會(huì)每次執(zhí)行時(shí)都進(jìn)行調(diào)用,對(duì)于性能方面,顯然③方式會(huì)比①②更好,而且②相對(duì)①對(duì)性能的影響會(huì)低一點(diǎn)。所以三者對(duì)性能優(yōu)化的優(yōu)先級(jí)為③>②>①
? ? ? React中,組件嵌套是十分常見的,在父組件往子組件傳遞對(duì)象時(shí),應(yīng)該將對(duì)象的key和value在render()內(nèi)先定義再使用,不然每一次使用子組件時(shí)都會(huì)生成新的對(duì)象進(jìn)行傳遞
如切忌使用:
正確的用法應(yīng)該是在render()內(nèi)先將對(duì)象定義,再在組件中調(diào)用

?在傳遞props/state時(shí),只傳遞需要的參數(shù)。

切忌將props/state以展開形式傳遞給子組件,除非子組件需要用到父組件的所有props/state
2. 多組件優(yōu)化
? ? ? 在父組件因狀態(tài)的變化更改,而子組件并沒有狀態(tài)變化時(shí),若子組件隨著父組件一起更新,會(huì)造成比較大的性能浪費(fèi),為減少子組件額外渲染而浪費(fèi)性能,可使用:
① shouldComponentUpdate(nextProps, nextState):
? ? 根據(jù)React組件的生命周期可以知道,組件在每次更新狀態(tài)時(shí)都會(huì)執(zhí)行shouldComponentUpdate函數(shù),為了減少額外渲染,可以在該函數(shù)內(nèi)對(duì)當(dāng)前的props/state與nextProps/nextState進(jìn)行比較,如果有一致的props/state則返回fasle說明不用重新渲染該組件,以減少重新渲染造成的性能浪費(fèi)。
② React.PureComponent 替換 React.Component:
? ? 在使用shouldComponentUpdate函數(shù)比較前后的props/state是否一致時(shí),通常會(huì)涉及到深層或淺層的比較,在React默認(rèn)進(jìn)行的淺層比較中,可以使用React.PureComponent讓組件根據(jù)傳來的數(shù)據(jù)進(jìn)行渲染而不是全部數(shù)據(jù)的渲染,這比自己寫shouldComponentUpdate函數(shù)進(jìn)行比較來的簡單且性能更好,但只適用于組件只根據(jù)傳進(jìn)來的數(shù)據(jù)進(jìn)行渲染而沒有內(nèi)部狀態(tài)時(shí)使用,可以最大限度的提升性能。
③ ImmutableJS:
? ? 在比較props/state時(shí),應(yīng)使用深層比較的形式,但要手動(dòng)寫shouldComponentUpdate函數(shù)的深層比較需要寫一個(gè)遞歸的函數(shù),通過層層遞歸比較出當(dāng)前值和next值的數(shù)據(jù)結(jié)構(gòu)是否相同,這在性能方面是不可接受的,所以React建議也是默認(rèn)的比較是只做淺對(duì)比,即不考慮props/state的數(shù)據(jù)結(jié)構(gòu),只考慮數(shù)值是否相同。所以在設(shè)計(jì)組件數(shù)據(jù)的傳遞時(shí),不應(yīng)做深層次的嵌套(如數(shù)據(jù)為對(duì)象,對(duì)象內(nèi)有多個(gè)值,值內(nèi)還是一個(gè)對(duì)象的形式)。而為了使組件在數(shù)據(jù)傳遞過程中保證渲染時(shí)當(dāng)前值與next值一定是不相同的,facebook提供了immutable-js這個(gè)庫,ImmutableJS提供了不可變的數(shù)據(jù),即要讓數(shù)據(jù)改變只能通過創(chuàng)建新數(shù)據(jù)的方式,而不能直接修改,這很大程度的降低了前后兩個(gè)數(shù)據(jù)比較時(shí)的復(fù)雜度。
3. Key
對(duì)于數(shù)組形式的數(shù)據(jù),遍歷時(shí)React會(huì)要求你為每一個(gè)數(shù)據(jù)值添加Key,而Key必須時(shí)獨(dú)一無二的,在選取Key值時(shí)盡量不要用索引號(hào),因?yàn)槿绻?dāng)數(shù)據(jù)的添加方式不是順序添加,而是以其他方式(逆序,隨機(jī)等),會(huì)導(dǎo)致每一次添加數(shù)據(jù),每一個(gè)數(shù)據(jù)值的索引號(hào)都不一樣,這就導(dǎo)致了Key的變化,而當(dāng)Key變化時(shí),React就會(huì)認(rèn)為這與之前的數(shù)據(jù)值不相同,會(huì)多次執(zhí)行渲染,會(huì)造成大量的性能浪費(fèi)。所以只在萬不得已時(shí),才將數(shù)據(jù)的Key設(shè)為索引號(hào)。
Redux性能優(yōu)化
? ? 使用reselect庫:
在使用Redux進(jìn)行數(shù)據(jù)的傳遞時(shí),特別是經(jīng)常有重復(fù)性的數(shù)據(jù)傳遞操作時(shí),可以使用reselect庫在內(nèi)部對(duì)數(shù)據(jù)進(jìn)行緩存處理,在重復(fù)調(diào)用時(shí)便可使用緩存快速加載,加強(qiáng)性能。
栗子(包含知識(shí)點(diǎn):react-redux, connect裝飾器寫法):
假設(shè)在redux中創(chuàng)建了addAge和subAge兩個(gè)action執(zhí)行減1和加1。

在上述例子中,如果對(duì)小明增加和減少歲數(shù)進(jìn)行重復(fù)操作,在調(diào)用到已經(jīng)執(zhí)行過的數(shù)據(jù)時(shí),react不會(huì)再次對(duì)數(shù)據(jù)進(jìn)行渲染,而是從reselector中取出緩存數(shù)據(jù)加載,減少了重新渲染,達(dá)到性能優(yōu)化的效果。