React組件優(yōu)化
? ? 1. 屬性傳遞優(yōu)化
在動態(tài)頁面中艳馒,免不了使用事件來監(jiān)控按鈕弄慰,React中便針對這種情況有相應(yīng)的優(yōu)化陆爽。以點(diǎn)擊事件onClick為例墓陈,在React中,事件的聲明方式有三種
① 事件在聲明時一起綁定
② 使用函數(shù)式聲明事件:
③ 在按鈕內(nèi)聲明,在constructor內(nèi)綁定:
? ? ? ? ? 三種聲明方式的比較:①②相對于③,再次執(zhí)行時都要再渲染一編render()里的bind函數(shù)和函數(shù)聲明式利花,而③的綁定函數(shù)只執(zhí)行一次载佳,并不會每次執(zhí)行時都進(jìn)行調(diào)用,對于性能方面蔫慧,顯然③方式會比①②更好,而且②相對①對性能的影響會低一點(diǎn)睡扬。所以三者對性能優(yōu)化的優(yōu)先級為③>②>①
? ? ? React中卖怜,組件嵌套是十分常見的马靠,在父組件往子組件傳遞對象時甩鳄,應(yīng)該將對象的key和value在render()內(nèi)先定義再使用娩贷,不然每一次使用子組件時都會生成新的對象進(jìn)行傳遞
如切忌使用:
正確的用法應(yīng)該是在render()內(nèi)先將對象定義彬祖,再在組件中調(diào)用
?在傳遞props/state時,只傳遞需要的參數(shù)突倍。
切忌將props/state以展開形式傳遞給子組件羽历,除非子組件需要用到父組件的所有props/state
2. 多組件優(yōu)化
? ? ? 在父組件因狀態(tài)的變化更改焊虏,而子組件并沒有狀態(tài)變化時,若子組件隨著父組件一起更新秕磷,會造成比較大的性能浪費(fèi)诵闭,為減少子組件額外渲染而浪費(fèi)性能,可使用:
① shouldComponentUpdate(nextProps, nextState):
? ? 根據(jù)React組件的生命周期可以知道澎嚣,組件在每次更新狀態(tài)時都會執(zhí)行shouldComponentUpdate函數(shù)疏尿,為了減少額外渲染,可以在該函數(shù)內(nèi)對當(dāng)前的props/state與nextProps/nextState進(jìn)行比較易桃,如果有一致的props/state則返回fasle說明不用重新渲染該組件褥琐,以減少重新渲染造成的性能浪費(fèi)。
② React.PureComponent 替換 React.Component:
? ? 在使用shouldComponentUpdate函數(shù)比較前后的props/state是否一致時晤郑,通常會涉及到深層或淺層的比較敌呈,在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)時使用,可以最大限度的提升性能。
③ ImmutableJS:
? ? 在比較props/state時荞下,應(yīng)使用深層比較的形式抽诉,但要手動寫shouldComponentUpdate函數(shù)的深層比較需要寫一個遞歸的函數(shù)河绽,通過層層遞歸比較出當(dāng)前值和next值的數(shù)據(jù)結(jié)構(gòu)是否相同句携,這在性能方面是不可接受的牍疏,所以React建議也是默認(rèn)的比較是只做淺對比,即不考慮props/state的數(shù)據(jù)結(jié)構(gòu),只考慮數(shù)值是否相同。所以在設(shè)計(jì)組件數(shù)據(jù)的傳遞時,不應(yīng)做深層次的嵌套(如數(shù)據(jù)為對象,對象內(nèi)有多個值搀愧,值內(nèi)還是一個對象的形式)眷蚓。而為了使組件在數(shù)據(jù)傳遞過程中保證渲染時當(dāng)前值與next值一定是不相同的叉钥,facebook提供了immutable-js這個庫,ImmutableJS提供了不可變的數(shù)據(jù)寝贡,即要讓數(shù)據(jù)改變只能通過創(chuàng)建新數(shù)據(jù)的方式,而不能直接修改风秤,這很大程度的降低了前后兩個數(shù)據(jù)比較時的復(fù)雜度。
3. Key
對于數(shù)組形式的數(shù)據(jù),遍歷時React會要求你為每一個數(shù)據(jù)值添加Key,而Key必須時獨(dú)一無二的,在選取Key值時盡量不要用索引號鳍贾,因?yàn)槿绻?dāng)數(shù)據(jù)的添加方式不是順序添加,而是以其他方式(逆序置森,隨機(jī)等),會導(dǎo)致每一次添加數(shù)據(jù),每一個數(shù)據(jù)值的索引號都不一樣,這就導(dǎo)致了Key的變化翁授,而當(dāng)Key變化時,React就會認(rèn)為這與之前的數(shù)據(jù)值不相同,會多次執(zhí)行渲染,會造成大量的性能浪費(fèi)详民。所以只在萬不得已時狞玛,才將數(shù)據(jù)的Key設(shè)為索引號。
Redux性能優(yōu)化
? ? 使用reselect庫:
在使用Redux進(jìn)行數(shù)據(jù)的傳遞時,特別是經(jīng)常有重復(fù)性的數(shù)據(jù)傳遞操作時上煤,可以使用reselect庫在內(nèi)部對數(shù)據(jù)進(jìn)行緩存處理劫狠,在重復(fù)調(diào)用時便可使用緩存快速加載苔埋,加強(qiáng)性能。
栗子(包含知識點(diǎn):react-redux, connect裝飾器寫法):
假設(shè)在redux中創(chuàng)建了addAge和subAge兩個action執(zhí)行減1和加1削罩。
在上述例子中糙麦,如果對小明增加和減少歲數(shù)進(jìn)行重復(fù)操作,在調(diào)用到已經(jīng)執(zhí)行過的數(shù)據(jù)時诽里,react不會再次對數(shù)據(jù)進(jìn)行渲染袒餐,而是從reselector中取出緩存數(shù)據(jù)加載,減少了重新渲染谤狡,達(dá)到性能優(yōu)化的效果灸眼。