天天看點

20170814-ReactReact

React

在Web開發中,要将更新的資料實時反映到UI上,就不可避免地需要對DOM進行操作,而複雜頻繁的DOM操作通常是産生性能瓶頸的原因之一。為此,React引入了

Virtual DOM

機制。

Virtual DOM

實際上是在浏覽器端用

JavaScript

實作的一套

DOM API

,它包括:

  • Virtual DOM

    模型
  • 生命周期的維護和管理
  • 性能高效的diff算法
  • Virtual DOM

    展示為原生DOM的

    Patch

    方法

基于React進行開發時,所有的DOM樹都是在

Virtual DOM

的基礎上構造的。React在

Virtual DOM

上實作了

DOM diff

算法,當資料更新時,會通過diff算法尋找到需要變更的DOM節點,并隻對變化的部分進行實際的浏覽器的DOM更新,而不是重新渲染整個DOM樹。

Virtual DOM

模型

ReactNode

  • ReactElement
    • ReactComponentElement
    • ReactDOMElement
  • ReactFragment
  • ReactText

建立React元素

通過JSX建立的虛拟元素最終會被編譯成調用React的

createElement

方法

初始化元件入口

當使用React建立元件時,首先會調用

instantiateReactComponent

,這是初始化元件的入口函數,它通過判斷node類型來區分不同元件的入口

文本元件

ReactDOMTextComponent

标簽元件

ReactDOMComponent

自定義元件

ReactCompositeComponent

生命周期

React的主要思想是通過建構可複用元件來建構使用者界面。所謂元件,就是有限狀态機,通過狀态渲染對應頁面,每個元件元件都有自己的生命周期,它規定了元件和方法需要在哪個階段改變和執行。

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

繼續閱讀