在說虛擬DOM之前,先來一個引子,從輸入url到展現出整個頁面都有哪些程序?
1、輸入網址
2、DNS決議
3、建立tcp連接
4、客戶端發送HTPP請求
5、服務器處理請求
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
ReactDOM.render 把虛擬dom轉成真實dom,并且掛載
ReactDOM.render會回傳對根組件
ReactComponent 實體的參考,但是目前應該避免使用回傳的參考,在未來版本的 React 中,組件渲染在某些情況下可能會是異步的, 如果你真的需要獲得對根組件 ReactComponent 實體的參考,那么推薦為根元素添加 callback ref,
當首次呼叫時,容器節點里的所有 DOM 元素都會被替換,后續的呼叫則會使用 React 的 DOM 差分演算法(DOM diffing algorithm)進行高效的更新,
ReactDOM.render() 不會修改容器節點(只會修改容器的子節點),
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/178080.html
標籤:JavaScript
上一篇:ES6物件簡潔語法
下一篇:LINE 專案總結
