react詳細介紹性能優化

今天給朋友們詳細介紹react如何進行性能優化。

首先要了解網頁性能不好的罪魁禍首

  瀏覽器的重繪和重排版(reflows&repaints)(DOM操作都會引起)纔是導致網頁性能問題的關鍵。
  而React虛擬DOM的目的就是爲了減少瀏覽器的重繪和重排版。

一:react中的問題

有時候組件的render方法會在不必要的情況下被調用。
比如:
  組件渲染的過程中,並沒有使用props或者state的值,或者組件的props或者state並沒有在父組件重新繪染時發生改變。這意味着重新繪染這個組件會得到和已知虛擬DOM一模一樣的結果。

二:優化關鍵shouldComponentUpdate

  組件更新生命週期中必調用shouldComponentUpdate,字面意思是組件是否應該更新。shouldComponentUpdate默認返回true,必定更新。所有當我們判斷出組件沒必要更新時,shouldComponentUpdate可以返回false,就達到優化效果。
shouldComponentUpdate生命週期有倆個參數,一個是nextProps,另一個是nextState,而我們就用這倆個上一次的props和state與這一次的props和state去做比較,如果倆者相同,那麼就return false,不讓它進行更新就可以了。
注意點:
shouldComponentUpdate()生命週期正常情況下只會進行淺比較。如果要進行深比較請繼續往下看。
深比較和淺比較涉及到堆內存和棧內存的知識點,可以觀看筆者的另外一篇博客去深入瞭解。
  事例代碼如下:

shouldComponentUpdate(nextProps,nextState) {
	if (nextProps === this.props && nextState === this.state)
		return false
	return true
}

如果說你的組件沒有用到props或者state可以把if判斷中對應的代碼去掉
**千萬注意!**不要把nextProps和nextState參數的順序弄混淆了,第一個參數固定是nextProps,第二個參數固定是nextState。

三:傳參優化

  React中,組件嵌套是十分常見的,在父組件往子組件傳遞對象時,應該將對象的key和value在render()內先定義再使用,不然每一次使用子組件時都會生成新的對象進行傳遞。
  切記將props/state以展開形式傳遞給子組件,除非子組件需要用到父組件的所有props/state。

四:多組件優化

  在父組件因狀態的變化更改,而子組件並沒有狀態變化時,若子組件隨着父組件一起更新,會造成比較大的性能浪費,爲減少子組件額外渲染而浪費性能,可使用的方法有:
1. shouldComponentUpdate()前面有介紹,忘了的朋友可以回退到上面第二個小標題觀看。
2. 使用React.PureComponent替換React.Component:(react的純組件,關於react的組件可觀看 筆者的react之入門介紹(1) )
  在使用shouldComponentUpdate函數比較前後的props/state是否一致時,通常會涉及到深層或淺層的比較,在React默認進行的淺層比較中,可以使用React.PureComponent讓組件根據傳來的數據進行渲染而不是全部數據的渲染,這比自己寫shouldComponentUpdate函數進行比較來的簡單且性能更好,但只適用於組件只根據傳進來的數據進行渲染而沒有內部狀態時使用,可以最大限度的提升性能。
3. ImmutableJS:
  在比較props/state時,應使用深層比較的形式,但要手動寫shouldComponentUpdate函數的深層比較需要寫一個遞歸的函數,通過層層遞歸比較出當前值和next值的數據結構是否相同,這在性能方面是不可接受的,所以React建議也是默認的比較是隻做淺對比,即不考慮props/state的數據結構,只考慮數值是否相同。所以在設計組件數據的傳遞時,不應做深層次的嵌套(如數據爲對象,對象內有多個值,值內還是一個對象的形式)。而爲了使組件在數據傳遞過程中保證渲染時當前值與next值一定是不相同的,facebook提供了immutable-js這個庫,ImmutableJS提供了不可變的數據,即要讓數據改變只能通過創建新數據的方式,而不能直接修改,這很大程度的降低了前後兩個數據比較時的複雜度。
  由於Immutable庫比較大,所以如果在React中引用該庫也是比較大的負擔,有一個Immutablejs庫的簡易版叫做seamless-immutable,該庫只支持Map,Set,List三種數據類型,但相對Immutable來說較小,對應用的負擔也小。

五:Key

  對於數組形式的數據,遍歷時React會要求你爲每一個數據值添加Key,而Key必須時獨一無二的,在選取Key值時儘量不要用索引號,因爲如果當數據的添加方式不是順序添加,而是以其他方式(逆序,隨機等),會導致每一次添加數據,每一個數據值的索引號都不一樣,這就導致了Key的變化,而當Key變化時,React就會認爲這與之前的數據值不相同,會多次執行渲染,會造成大量的性能浪費。所以只在萬不得已時,纔將數據的Key設爲索引號。

六:引入react-loadable做分片打包

引入該插件後可以如下使用,實現組件的按需加載,大大提高頁面速度。

import Loadable from 'react-loadable'
import Loading from './Loading'  //Loading頁面導出一個方法,return一個null或者其他的出來
import { xxx } from 'xxx'	//引入你的頁面

const test = Loadable({
    loader:() => import('./NotFound'),	//你的文件位置
    loading:Loading
})

export {
	xxx,
	test,
}

小總結:
1. 後端返回數據的高度統一性,例如都是{data:[…],hasMore:true}這種形式
2. 前端組件的高度拆分和抽象,以便做到最大極限的靈活拼接。

Redux性能優化:

一:使用reselect庫
  在使用Redux進行數據的傳遞時,特別是經常有重複性的數據傳遞操作時,可以使用reselect庫在內部對數據進行緩存處理,在重複調用時便可使用緩存快速加載,加強性能。
  在調用到已經執行過的數據時,react不會再次對數據進行渲染,而是從reselector中取出緩存數據加載,減少了重新渲染,達到性能優化的效果。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章