【日拱一卒】React原理 一 Virtual DOM 下

語言: CN / TW / HK

這是我參與11月更文挑戰的第27天,活動詳情檢視:2021最後一次更文挑戰

前言

VirtualDOM是什麼VirtualDOM Diff高效的原因

Virtual DOM Diff

Virtual DOM如何提高效能

  1. 我們將render產生的VirtualDOM簡稱'Vdom'
  2. 通常呼叫setState方法觸發Vdom更新
  3. 通過對比新舊'Vdom',確定最優實現新'Vdom'所需的操作  

這裡的Virtual DOM diff 也是指第三步。不被我們平時所在意的一個步驟。

Virtual DOM Diff的層次

  • 元件級別的比較
  • 元素級別的比較

因為我們通常一個HTML節點是一棵完整的樹,完整的樹遍歷時間複雜度為O(n^3)

而Virtual DOM對HTML層級節點的劃分,遍歷所有節點的時間複雜度為O(n^0)

這也是使得Virtual DOM比較高效的原因之一

Component Diff

R - 入口App A - 配置頁面1 D - 配置頁面2 G - 配置頁面3

當前需求把D(配置元件2)轉換為G(配置頁面3)

雖然D、G  元件 有相同的EF,但是這裡還是會把D、E、F元件全部刪掉,再去重新建立G、E、F元件。(因為有相同的EF子元件畢竟還是小概率事件,現實場景中,EF下可能有很多個子元件,難以做到一個一個全部比對,做到了也十分低效,不如全部刪掉,這個只是個人感受,不做理論的論證,先給個定論,感興趣有時間可以探討)

Element Diff

建立、移動、刪除子節點  對應了DOM操作中的建立、移動、刪除

建立節點

create: function (child, afterNode,mountImage){
    return makeInsertMarkup(mountImage,afterNode,child._mountIndex);
}

刪除節點

removeChild: function (child, node){
    return makeRemove(child, node)
}

移動節點

1-2-3  =》 3-1-2

react實現是把1挪到3後面,再把2挪到3後面,這樣的操作是比較低效的,儘量要規避把最後一個節點移動到最前面的情況

協調reconciliation

最後一句話this process is called reconciliation

Virtual DOM diff是React協調中的一個環節,而在React15的版本中這個協調叫做棧協調(Stack Reconciler)

過程回顧

  • render 執行render
  • Virtual Diff 比較Virtual dom
  • commit 確定需要更新則執行更新 (不可阻斷)

因不可阻斷,如果執行中使用者產生了互動行為,頁面可能相應不過來,發生卡頓。

React16推出了一個新的協調方法

總結

  • Virtual DOM本質是對UI節點的抽象。只是在Web開發中,具體化為對HTML DOM節點的抽象。這也是前端逐漸跨平臺化的一種體現。
  • Virtual DOM比原生高效的原因,一是Diff演算法的高效,實現了高效的更新,另一個是可維護性和程式設計思維上的高效。

參考連結

官網Virtual Dom https://reactjs.org/docs/faq-internals.html#what-is-the-virtual-dom

Virtual DOM Node https://mithril.js.org/vnodes.html

VDom與 DOM 的區別 https://reactkungfu.com/2015/10/the-difference-between-virtual-dom-and-dom/

React效能優化:Virtual Dom原理淺析

[譯] Virtual Dom 和 Diff 演算法

PS: React的水越來越深了,感覺已經不太適合用來玩這種短平快的更文了。換一個模組試試吧。