20170814-React

React

在Web開發中,要將更新的數據實時反映到UI上,就不可避免地須要對DOM進行操做,而複雜頻繁的DOM操做一般是產生性能瓶頸的緣由之一。爲此,React引入了Virtual DOM機制。Virtual DOM其實是在瀏覽器端用JavaScript實現的一套DOM API,它包括:node

  • Virtual DOM模型
  • 生命週期的維護和管理
  • 性能高效的diff算法
  • Virtual DOM展現爲原生DOM的Patch方法

基於React進行開發時,全部的DOM樹都是在Virtual DOM的基礎上構造的。React在Virtual DOM上實現了DOM diff算法,當數據更新時,會經過diff算法尋找到須要變動的DOM節點,並只對變化的部分進行實際的瀏覽器的DOM更新,而不是從新渲染整個DOM樹。react

Virtual DOM模型

ReactNode

  • ReactElement算法

    • ReactComponentElement
    • ReactDOMElement
  • ReactFragment
  • ReactText

建立React元素

經過JSX建立的虛擬元素最終會被編譯成調用React的createElement方法瀏覽器

初始化組件入口

當使用React建立組件時,首先會調用instantiateReactComponent,這是初始化組件的入口函數,它經過判斷node類型來區分不一樣組件的入口dom

文本組件

ReactDOMTextComponent函數

標籤組件

ReactDOMComponent性能

自定義組件

ReactCompositeComponentcode

生命週期

React的主要思想是經過構建可複用組件來構建用戶界面。所謂組件,就是有限狀態機,經過狀態渲染對應頁面,每一個組件組件都有本身的生命週期,它規定了組件和方法須要在哪一個階段改變和執行。component

diff算法

diff算法會幫助咱們計算出Virtual DOM中真正變化的部分,並只針對該部分進行原生DOM操做,而非從新渲染整個頁面,從而保證了每次操做更新後頁面的高效渲染。遞歸

傳統diff算法

  • 計算一顆樹形結構轉換成另外一棵樹形結構的最少操做
  • 傳統算法經過循環遞歸對節點進行一次對比,算法複雜度達到O(n³)

React對diff算法的改進

React結合DOM樹的特色,對傳統diff算法進行了改進,將其轉換爲O(n)複雜度的問題

React diff算法的三個策略

  • Web UI中DOM節點跨層級的操做較少(若是有,能夠理解爲刪去一個節點,在另外一層級插入新節點)
  • 擁有相同類的兩個組件會生成類似的樹形結構,擁有不一樣類的兩個組件將會生成不一樣的樹形結構
  • 對於同一層級的一組子節點,它們能夠經過惟一的id進行區分

tree diff(上面的第一個策略)

  • 對樹進行分層比較,兩顆樹只會對同一層次的節點進行比較
  • React只會簡單地考慮同層級節點的位置變換,而對於不一樣層級的節點,只有建立和刪除操做
  • 在開發組件時,保持穩定的DOM結構有助於性能的提高,建議不要進行DOM節點跨層級的操做

component diff(第二個策略)

  • 若是是同一類型的組件,則按照原策略繼續比較Virtual DOM
  • 若是不是同一類型的組件,則將舊組件直接刪除,在該位置從新建立新組件
  • 若是是同一類型的組件,有可能其Virtual DOM沒有任何變化,若是咱們可以明確知道這點,這能夠利用shouldComponentUpdate()來判斷組件是否須要進行diff算法分析

element diff(第三個策略)

  • 當節點處於同一層級時,diff算法提供了3中節點操做,分別爲插入、移動、刪除
  • 對於同一層級的同組子節點,須要添加惟一key進行區分,經過這種方法來解決相同節點位置變化的狀況

React Patch方法

將diff算法計算出來的DOM差別隊列更新到真實的DOM節點上,最終讓瀏覽器可以渲染出更新的數據。

(未完待續...)

參考

深刻淺出React

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息