一、是什麼

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完全增刪改+排版與重繪”

之前文章舉過的例子:

傳統的原生apijQuery去操作DOM時,瀏覽器會從構建DOM樹開始從頭到尾執行一遍流程

當你在一次操作時,需要更新10個DOM節點,瀏覽器沒這麼智慧,收到第一個更新DOM請求後,並不知道後續還有9次更新操作,因此會馬上執行流程,最終執行10次流程

而通過VNode,同樣更新10個DOM節點,虛擬DOM不會立即操作DOM,而是將這10次更新的diff內容儲存到本地的一個js物件中,最終將這個js物件一次性attachDOM樹上,避免大量的無謂計算

三、優缺點

真實DOM的優勢:

  • 易用

缺點:

  • 效率低,解析速度慢,記憶體佔用量過高
  • 效能差:頻繁操作真實DOM,易於導致重繪與迴流

使用虛擬DOM的優勢如下:

  • 簡單方便:如果使用手動操作真實DOM來完成頁面,繁瑣又容易出錯,在大規模應用下維護起來也很困難

  • 效能方面:使用Virtual DOM,能夠有效避免真實DOM數頻繁更新,減少多次引起重繪與迴流,提高效能

  • 跨平臺:React藉助虛擬DOM, 帶來了跨平臺的能力,一套程式碼多端執行

缺點:

  • 在一些效能要求極高的應用中虛擬 DOM 無法進行鍼對性的極致優化
  • 首次渲染大量DOM時,由於多了一層虛擬DOM的計算,速度比正常稍慢