visual Dom是什么??
虛擬DOM其實(shí)就是瞬痘,像擁有類似dom的一系列屬性的對(duì)象,包括:標(biāo)簽名运悲,標(biāo)簽上的屬性晶通,事件監(jiān)聽,和子元素們华望,以及其他的相關(guān)屬性蕊蝗;
React
和Vue
的本質(zhì)就是虛擬DOM
// React
const reactNode = {
key: null.
props: {
children: [{ // 子元素們
type: 'span',
...
}],
className: "red", // 標(biāo)簽上的屬性
onClick: () => {} // 事件
},
ref: null
type: "div" // 標(biāo)簽名 or 組件名
...
}
// Vue
const vNode = {
tag: "div", // 標(biāo)簽名 or 組件名
data: {
class: "red", // 標(biāo)簽上的屬性
on: {
click: () => {} // 事件
}
},
children: [ // 子元素們
{ tag: "span", ... },
{ tag: "span", ... }
],
...
}
虛擬 DOM 的優(yōu)點(diǎn) ?
- 減少DOM操作
- 減少頻次
比如往頁(yè)面添加1000個(gè)節(jié)點(diǎn)原生js一個(gè)接一個(gè)的操作,虛擬DOM可以將多次操作合并成一次操作 - 減少范圍
當(dāng)需要更新1000 個(gè)節(jié)點(diǎn)時(shí)赖舟,虛擬DOM借助DOM diff對(duì)比蓬戚,省去多余的操作
- 跨平臺(tái)
由于虛擬DOM本質(zhì)上就是一個(gè)js對(duì)象,他可以變成DOM宾抓,還可以變成IOS應(yīng)用子漩、安卓應(yīng)用豫喧,小程序等各平臺(tái)的應(yīng)用。
虛擬 DOM 的缺點(diǎn) ?
有一個(gè)缺點(diǎn)就是幢泼,需要使用額外的創(chuàng)建函數(shù)去創(chuàng)建紧显,比如React是React.createElement,Vue而是放在了render函數(shù)中(h)缕棵,但是呢孵班,寫法看起來(lái)確實(shí)不太友好
// React
createElement('div',{className:'red',onClick:()=> {}},[
createElement('span', {}, 'span1'),
createElement('span', {}, 'span2')
]
)
// Vue
h('div', {
class: 'red',
on: {
click: () => { }
},
}, [h('span',{},'span1'), h('span', {}, 'span2'])
于是,React采用了JSX語(yǔ)法招驴,Vue使用Template模板篙程,即可優(yōu)雅的
創(chuàng)建虛擬DOM了
// React
<div className="red" onClick={fn}>
<span>span1</span>
<span>span2</span>
</div>
// 后面將通過(guò)babel 轉(zhuǎn)換為 createElement形式
// Vue
<div class="red" @click="fn">
<span>span1</span>
<span>span2</span>
</div>
// 后面將通過(guò)vue-loader轉(zhuǎn)換為 h 形式
DOM diff ??
diff 就是“區(qū)別,對(duì)比”的意思别厘,也就是:虛擬DOM的對(duì)比虱饿;
當(dāng)你把虛擬DOM看做是樹形,按照根左右(先序深度優(yōu)先)丹允,對(duì)比兩顆樹郭厌。
從標(biāo)簽類型
、對(duì)應(yīng)的屬性
雕蔽、子元素
上對(duì)比折柠,兩棵樹的不同,最后會(huì)返回一個(gè)patchs對(duì)象批狐,用來(lái)存儲(chǔ)兩個(gè)節(jié)點(diǎn)不同的地方扇售,最后用patchs記錄的消息去局部更新Dom
大概的格式可能是這樣
[{
type: 'insert',
value: ...
}, {
type: 'move',
value: ...
}, {
type: 'remove',
value: ...
}]
DOM diff 的邏輯
DOM diff 的優(yōu)點(diǎn)??
上面提到過(guò),可以縮減dom操作范圍
DOM diff 的問(wèn)題??
如何保證DOM diff 在查找對(duì)比的時(shí)候不會(huì)出錯(cuò)嚣艇,就需要通過(guò)指定唯一key值承冰,提高準(zhǔn)確率也就是對(duì)比效率
虛擬DOM的優(yōu)勢(shì)是——優(yōu)化性能嗎?
我們知道食零,在客戶端渲染進(jìn)程中困乒,js代碼調(diào)用 DOM API,會(huì)掛起JS 線程贰谣,切換到GUI 線程(Graphical User Interface)進(jìn)行重排娜搂、重繪等操作;如果有頻繁的DOM API調(diào)用吱抚,引擎之間的切換單位代價(jià)百宇,將重復(fù)積累。重排和重繪秘豹,會(huì)引起更大的性能消耗携御。
- V-DOM不會(huì)立馬重排,而是將多個(gè)重復(fù)的操作合并成一個(gè)
- V-DOM會(huì)通過(guò)對(duì)比算法,識(shí)別出需要修改的節(jié)點(diǎn)啄刹,省去多余操作
在全部更新的情況下涮坐,V-DOM其實(shí)沒(méi)什么優(yōu)勢(shì),原生操作DOM反而更快鸵膏,當(dāng)只有一部分?jǐn)?shù)據(jù)變化時(shí)膊升,可以以最小代價(jià)的更新DOM
也就是說(shuō),其實(shí)虛擬DOM的優(yōu)點(diǎn)可以概括為:
- 為函數(shù)式的UI編程打開大門
- 可以渲染到DOM以外的后臺(tái)(例如:ReactNative)谭企,即利于跨平臺(tái)開發(fā)