一、是什麼
Real DOM,真實DOM
, 意思為文件物件模型,是一個結構化文字的抽象,在頁面渲染出的每一個結點都是一個真實DOM
結構,如下:
Virtual Dom
,本質上是以 JavaScript
物件形式存在的對 DOM
的描述
建立虛擬DOM
目的就是為了更好將虛擬的節點渲染到頁面檢視中,虛擬DOM
物件的節點與真實DOM
的屬性一一照應
在React
中,JSX
是其一大特性,可以讓你在JS
中通過使用XML
的方式去直接宣告介面的DOM
結構
const vDom = <h1>Hello World</h1> // 建立h1標籤,右邊千萬不能加引號
const root = document.getElementById('root') // 找到<div id="root"></div>節點
ReactDOM.render(vDom, root) // 把建立的h1標籤渲染到root節點上
上述中,ReactDOM.render()
用於將你建立好的虛擬DOM
節點插入到某個真實節點上,並渲染到頁面上
JSX
實際是一種語法糖,在使用過程中會被babel
進行編譯轉化成JS
程式碼,上述VDOM
轉化為如下:
const vDom = React.createElement(
'h1',
{ className: 'hClass', id: 'hId' },
'hello world'
)
可以看到,JSX
就是為了簡化直接呼叫React.createElement()
方法:
第一個引數是標籤名,例如h1、span、table...
第二個引數是個物件,裡面存著標籤的一些屬性,例如id、class等
第三個引數是節點中的文字
通過console.log(VDOM)
,則能夠得到虛擬VDOM
訊息
所以可以得到,JSX
通過babel
的方式轉化成React.createElement
執行,返回值是一個物件,也就是虛擬DOM
二、區別
兩者的區別如下:
- 虛擬DOM不會進行排版與重繪操作,而真實DOM會頻繁重排與重繪
- 虛擬DOM的總損耗是“虛擬DOM增刪改+真實DOM差異增刪改+排版與重繪”,真實DOM的總損耗是“真實DOM完全增刪改+排版與重繪”
拿之前文章舉過的例子:
傳統的原生api
或jQuery
去操作DOM
時,瀏覽器會從構建DOM
樹開始從頭到尾執行一遍流程
當你在一次操作時,需要更新10個DOM
節點,瀏覽器沒這麼智慧,收到第一個更新DOM
請求後,並不知道後續還有9次更新操作,因此會馬上執行流程,最終執行10次流程
而通過VNode
,同樣更新10個DOM
節點,虛擬DOM
不會立即操作DOM
,而是將這10次更新的diff
內容儲存到本地的一個js
物件中,最終將這個js
物件一次性attach
到DOM
樹上,避免大量的無謂計算
三、優缺點
真實DOM
的優勢:
- 易用
缺點:
- 效率低,解析速度慢,記憶體佔用量過高
- 效能差:頻繁操作真實DOM,易於導致重繪與迴流
使用虛擬DOM
的優勢如下:
簡單方便:如果使用手動操作真實
DOM
來完成頁面,繁瑣又容易出錯,在大規模應用下維護起來也很困難效能方面:使用Virtual DOM,能夠有效避免真實DOM數頻繁更新,減少多次引起重繪與迴流,提高效能
跨平臺:React藉助虛擬DOM, 帶來了跨平臺的能力,一套程式碼多端執行
缺點:
- 在一些效能要求極高的應用中虛擬 DOM 無法進行鍼對性的極致優化
- 首次渲染大量DOM時,由於多了一層虛擬DOM的計算,速度比正常稍慢