淺談Vue中的虛擬DOM

Virtual DOM 是JavaScript按照DOM的結(jié)構(gòu)來(lái)創(chuàng)建的虛擬樹(shù)型結(jié)構(gòu)對(duì)象,是對(duì)DOM的抽象,比DOM更加輕量型
為啥要使用Virtual DOM
當(dāng)然是前端優(yōu)化方面,避免頻繁操作DOM,頻繁操作DOM會(huì)可能讓瀏覽器回流和重繪,性能也會(huì)非常低,還有就是手動(dòng)操作 DOM 還是比較麻煩的,要考慮瀏覽器兼容性問(wèn)題,當(dāng)前jQuery等庫(kù)簡(jiǎn)化了 DOM操作,但是項(xiàng)目復(fù)雜了,DOM操作還是會(huì)變得復(fù)雜,數(shù)據(jù)操作也變得復(fù)雜
并不是所有情況使用虛擬DOM 都提高性能,是針對(duì)在復(fù)雜的的項(xiàng)目使用。如果簡(jiǎn)單的操作,使用虛擬DOM,要?jiǎng)?chuàng)建虛擬DOM對(duì)象等等一系列操作,還不如普通的DOM 操作
虛擬DOM 可以實(shí)現(xiàn)跨平臺(tái)渲染,服務(wù)器渲染 、小程序、原生應(yīng)用都使用了虛擬DOM
使用虛擬DOM改變了當(dāng)前的狀態(tài)不需要立即的去更新DOM 而且更新的內(nèi)容進(jìn)行更新,對(duì)于沒(méi)有改變的內(nèi)容不做任何操作,通過(guò)前后兩次差異進(jìn)行比較
虛擬 DOM 可以維護(hù)程序的狀態(tài),跟蹤上一次的狀態(tài)
在Web早期,頁(yè)面的交互比較簡(jiǎn)單,沒(méi)有復(fù)雜的狀態(tài)需要管理,也不太需要頻繁的操作DOM,隨著時(shí)代的發(fā)展,頁(yè)面上的功能越來(lái)越多,我們需要實(shí)現(xiàn)的需求也越來(lái)越復(fù)雜,DOM的操作也越來(lái)越頻繁。通過(guò)js操作DOM的代價(jià)很高,因?yàn)闀?huì)引起頁(yè)面的重排重繪,增加瀏覽器的性能開(kāi)銷(xiāo),降低頁(yè)面渲染速度,既然操作dom的代價(jià)很高那么有沒(méi)有那種方式可以減少對(duì)dom的操作?這就是為什么提出虛擬dom一個(gè)很重要的原因。
淺談Vue中的虛擬DOM
在正式介紹Virtual DOM之前,我們有必要先了解下模版轉(zhuǎn)換成視圖的整個(gè)過(guò)程(如下圖):
Vue.js通過(guò)編譯將模版轉(zhuǎn)換成渲染函數(shù)(render),執(zhí)行渲染函數(shù)就可以得到一個(gè)虛擬DOM 在對(duì)模型進(jìn)行操作的時(shí)候,會(huì)觸發(fā)對(duì)應(yīng)的Dep中的Watcher對(duì)象。Watcher對(duì)象會(huì)調(diào)用對(duì)應(yīng)的update來(lái)修改視圖。這個(gè)過(guò)程主要是將新舊虛擬DOM進(jìn)行差異對(duì)比,然后根據(jù)結(jié)果進(jìn)行對(duì)比。
簡(jiǎn)單點(diǎn)講,在Vue的實(shí)現(xiàn)上,Vue講模版編譯成虛擬DOM渲染函數(shù)。結(jié)合Vue自帶的響應(yīng)系統(tǒng),在狀態(tài)改變時(shí),Vue能夠智能地計(jì)算出重新渲染組件的最小代價(jià)并應(yīng)用到DOM操作上。

我們先對(duì)上圖幾個(gè)概念嵌入解釋?zhuān)?br>
渲染函數(shù):渲染函數(shù)是用來(lái)生成虛擬DOM的。Vue推薦使用模版來(lái)構(gòu)建我們的應(yīng)用界面,在實(shí)現(xiàn)中Vue布局模版編譯成渲染函數(shù),當(dāng)然我們也可以不寫(xiě)模版,直接寫(xiě)渲染函數(shù),這樣子更接近編譯后的模版。
vnode虛擬節(jié)點(diǎn):它可以代表一個(gè)真實(shí)的DOM節(jié)點(diǎn)通過(guò)createElement方法能將vnode渲染成DOM節(jié)點(diǎn),簡(jiǎn)單地說(shuō),虛擬節(jié)點(diǎn)可以理解成節(jié)點(diǎn)描述對(duì)象,它描述了應(yīng)該怎樣去創(chuàng)建真實(shí)的DOM節(jié)點(diǎn)。
patch(也稱(chēng)為patching算法):虛擬DOM最核心的部分,它可以將vnode渲染成真實(shí)的DOM,這個(gè)過(guò)程是對(duì)比新舊虛擬節(jié)點(diǎn)之間有哪些不同,然后根據(jù)對(duì)比結(jié)果找出需要更新的的節(jié)點(diǎn)進(jìn)行更新。這點(diǎn)我們從單詞含義就可以看出, patch本身就有補(bǔ)丁、修補(bǔ)的意思,其實(shí)際作用是在現(xiàn)有DOM上進(jìn)行修改來(lái)實(shí)現(xiàn)更新視圖的目的。Vue的Virtual DOM Patching算法是基于Snabbdom的實(shí)現(xiàn),并在些基礎(chǔ)上作了很多的調(diào)整和改進(jìn)。
