一、是什么
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的計算,速度比正常稍慢