React 效能最佳化總結

來源:互聯網
上載者:User

標籤:產生   cto   ast   跳過   論壇   dom操作   als   com   簡單   

初學者對React可能滿懷期待,覺得React可能完爆其它一切架構,甚至不切實際地認為React可能連原生的渲染都能完爆——對架構的狂熱確實會出現這樣的不切實際的期待。讓我們來看看React的官方是怎麼說的。React官方文檔在Advanced Performanec這一節,這樣寫道:

One of the first questions people ask when considering React for a project is whether their application will be as fast and responsive as an equivalent non-React version
顯然React自己也其實只是想盡量達到跟非React版本相若的效能,

你所不知道的render

react的組件渲染分為初始化渲染和更新渲染。在初始化渲染的時候會調用根組件下的所有組件的render方法進行渲染,如(綠色表示已渲染,這一層是沒有問題的):

 

但是當我們要更新某個子組件的時候,如的綠色組件(從根組件傳遞下來應用在綠色組件上的資料發生改變):

 

我們的理想狀態是只調用關鍵路徑上組件的render,如:

 

但是react的預設做法是調用所有組件的render,萬花樓論壇再對產生的虛擬DOM進行對比,如不變則不進行更新。這樣的render和虛擬DOM的對比明顯是在浪費,如(黃色表示浪費的render和虛擬DOM對比)

 

Tips:
拆分組件是有利於複用和組件最佳化的。
產生虛擬DOM並進行比對發生在render()後,而不是render()前。
更新階段的生命週期

componentWillReceiveProps(object nextProps):當掛載的組件接收到新的props時被調用。此方法應該被用於比較this.props 和 nextProps以用於使用this.setState()執行狀態轉換。(組件內部資料有變化,使用state,但是在更新階段又要在props改變的時候改變state,則在這個生命週期裡面)
shouldComponentUpdate(object nextProps, object nextState): -boolean 當組件決定任何改變是否要更新到DOM時被調用。作為一個最佳化實現比較this.props 和 nextProps 、this.state 和 nextState ,如果React應該跳過更新,返回false。
componentWillUpdate(object nextProps, object nextState):萬花樓論壇www.whlwang.com在更新發生前被立即調用。你不能在此調用this.setState()。
componentDidUpdate(object prevProps, object prevState): 在更新發生後被立即調用。(可以在DOM更新完之後,做一些收尾的工作)
Tips:
React的最佳化是基於shouldComponentUpdate的,該生命週期預設返回true,所以一旦prop或state有任何變化,都會引起重新render。
shouldComponentUpdate

react在每個組件生命週期更新的時候都會調用一個shouldComponentUpdate(nextProps, nextState)函數。它的職責就是返回true或false,true表示需要更新,false表示不需要,預設返回為true,即便你沒有顯示地定義 shouldComponentUpdate 函數。這就不難解釋上面發生的資源浪費了。

為了進一步說明問題,我們再引用一張官網的圖來解釋,如( SCU表示shouldComponentUpdate,綠色表示返回true(需要更新),紅色表示返回false(不需要更新);vDOMEq表示虛擬DOM比對,綠色表示一致(不需要更新),紅色表示發生改變(需要更新)):

 

根據渲染流程,首先會判斷shouldComponentUpdate(SCU)是否需要更新。如果需要更新,則調用組件的render產生新的虛擬DOM,然後再與舊的虛擬DOM對比(vDOMEq),如果對比一致就不更新,如果對比不同,則根據最小粒度改變去更新DOM;如果SCU不需要更新,則直接保持不變,同時其子項目也保持不變。

C1根節點,綠色SCU (true),表示需要更新,然後vDOMEq紅色,表示虛擬DOM不一致,需要更新。
C2節點,紅色SCU (false),表示不需要更新,所以C4,C5均不再進行檢查
C3節點同C1,需要更新
C6節點,綠色SCU (true),表示需要更新,然後vDOMEq紅色,表示虛擬DOM不一致,更新DOM。
C7節點同C2
C8節點,綠色SCU (true),表示需要更新,然後vDOMEq綠色,表示虛擬DOM一致,不更新DOM。
帶坑的寫法:

{…this.props} (不要濫用,請只傳遞component需要的props,傳得太多,或者層次傳得太深,都會加重shouldComponentUpdate裡面的資料比較負擔,因此,也請慎用spread attributes(<Component {…props} />))。
::this.handleChange()。(請將方法的bind一律置於constructor)
this.handleChange.bind(this,id)
複雜的頁面不要在一個組件裡面寫完。
請盡量使用const element。
map裡面添加key,並且key不要使用index(可變的)。具體可參考使用Perf工具研究React Key對渲染的影響
盡量少用setTimeOut或不可控的refs、DOM操作。
資料儘可能簡單明了,扁平化。

React 效能最佳化總結

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.