在說虛擬DOM之前,先來一個引子,從輸入url到展現出整個頁面都有哪些過程? 1、輸入網址 2、DNS解析 3、建立tcp連接 4、客戶端發送HTPP請求 5、伺服器處理請求 6、伺服器響應請求 7、瀏覽器展示HTML 8、瀏覽器發送請求獲取其他在HTML中的資源。 其中瀏覽器展示HTML經過了:構 ...
在說虛擬DOM之前,先來一個引子,從輸入url到展現出整個頁面都有哪些過程?
1、輸入網址
2、DNS解析
3、建立tcp連接
4、客戶端發送HTPP請求
6、伺服器響應請求
7、瀏覽器展示HTML
8、瀏覽器發送請求獲取其他在HTML中的資源。
其中瀏覽器展示HTML經過了:構建DOM樹,解析CSS構建CSSOM樹,DOM與CSSOM結合成為RenderObject樹,然後將RenderObject樹渲染成頁面(佈局->重繪),這個過程是由渲染引擎做的,JavaScript引擎與渲染引擎是獨立的,因為js可以操作dom,所以渲染引擎會暴露給js引擎一些介面來操作dom元素,這個通信過程的耗費是比較大的,所以在性能優化中會有一條:js儘量少操作dom元素,而虛擬DOM則是為瞭解決這一問題而出現。
當你用傳統的源生api或jQuery去操作DOM時,瀏覽器會從構建DOM樹開始從頭到尾執行一遍流程。比如當你在一次操作時,需要更新10個DOM節點,理想狀態是一次性構建完DOM樹,再執行後續操作。但瀏覽器沒這麼智能,收到第一個更新DOM請求後,並不知道後續還有9次更新操作,因此會馬上執行流程,最終執行10次流程。顯然例如計算DOM節點的坐標值等都是白白浪費性能,可能這次計算完,緊接著的下一個DOM更新請求,這個節點的坐標值就變了,前面的一次計算是無用功。
虛擬DOM就是為瞭解決這個瀏覽器性能問題而被設計出來的。例如前面的例子,假如一次操作中有10次更新DOM的動作,虛擬DOM不會立即操作DOM,而是將這10次更新的diff內容保存到本地的一個js對象中,最終將這個js對象一次性attach到DOM樹上,通知瀏覽器去執行繪製工作,這樣可以避免大量的無謂的計算量。
什麼是虛擬DOM?
Virtual DOM 是一種編程概念。在這個概念里, UI 以一種理想化的,或者說“虛擬的”表現形式被保存於記憶體中,並通過如 ReactDOM 等類庫使之與“真實的” DOM 同步。這一過程叫做協調。
在某一時間節點調用 React 的 render()
方法,會創建一棵由 React 元素組成的樹。在下一次 state 或 props 更新時,相同的 render()
方法會返回一棵不同的樹。React 需要基於這兩棵樹之間的差別來判斷如何有效率的更新 UI 以保證當前 UI 與最新的樹保持同步。(Diffing演算法)
這種方式賦予了 React 聲明式的 API:您告訴 React 希望讓 UI 是什麼狀態,React 就確保 DOM 匹配該狀態。這使您可以從屬性操作、事件處理和手動 DOM 更新這些在構建應用程式時必要的操作中解放出來。
如何創建虛擬dom
JSX就是在創建虛擬DOM,JSX就是React.createElement(component, props, ...children)的語法糖
<MyButton color="blue" shadowSize={2}> Click Me </MyButton>
會被babel轉譯成
React.createElement( MyButton, {color: 'blue', shadowSize: 2}, 'Click Me' )
React.createElement()
會預先執行一些檢查,以幫助你編寫無錯代碼,但實際上它創建了一個這樣的對象:
// 註意:這是簡化過的結構 const element = { type: 'h1', props: { className: 'greeting', children: 'Hello, world!' } };
也就是=》react元素
ReactDOM.render 把虛擬dom轉成真實dom,並且掛載