虛擬DOM最核心的部分是patch盟广,它可以將vnode渲染成真實(shí)的DOM。
patch也可以叫做patching算法祖搓,通過(guò)它渲染真實(shí)的DOM時(shí)狱意,并不是暴力覆蓋原有DOM,而是對(duì)比新舊兩個(gè)vnode之間的不同個(gè)拯欧,根據(jù)對(duì)比結(jié)果找出需要更新的節(jié)點(diǎn)進(jìn)行更新详囤。其實(shí)際作用是在現(xiàn)有的DOM上進(jìn)行修改來(lái)實(shí)現(xiàn)更新視圖的目的。
之所以這么做镐作,是因?yàn)镈OM操作的執(zhí)行速度遠(yuǎn)不如JavaScript的運(yùn)算速度快藏姐。因此,把大量的DOM操作搬運(yùn)到JavaScript中该贾,使用patching算法來(lái)計(jì)算出真正需要更新的節(jié)點(diǎn)羔杨,最大限度的減少DOM操作,從而顯著提升性能杨蛋。本質(zhì)上其實(shí)使用JavaScript的運(yùn)算成本來(lái)替換DOM操作的執(zhí)行成本兜材,而JavaScript的運(yùn)算速度比DOM快很多理澎,這樣做很劃算,所以才會(huì)有虛擬DOM曙寡。
patch介紹
對(duì)比兩個(gè)vnode之間的差異只是patch的一部分糠爬,這是手段不是目的。patch的目的其實(shí)是修改DOM節(jié)點(diǎn)举庶。也可以理解成渲染視圖执隧。上面說(shuō)過(guò)patch不是暴力替換節(jié)點(diǎn),而是在現(xiàn)有的DOM上進(jìn)行修改來(lái)達(dá)到渲染視圖的目的灯变。對(duì)現(xiàn)有的DOM進(jìn)行修改需要做三件事:
- 創(chuàng)建新增的節(jié)點(diǎn)殴玛;
- 刪除已經(jīng)廢棄的節(jié)點(diǎn);
- 修改需要更新的節(jié)點(diǎn)添祸;
我們知道patch的過(guò)程其實(shí)就是創(chuàng)建節(jié)點(diǎn)滚粟、刪除節(jié)點(diǎn)和修改節(jié)點(diǎn)的過(guò)程,接下來(lái)主要討論在上面情況下創(chuàng)建新節(jié)點(diǎn)刃泌,插入到上面位置凡壤;在上面情況下刪除節(jié)點(diǎn),刪除哪個(gè)節(jié)點(diǎn)耙替;在上面情況下修改節(jié)點(diǎn)亚侠,修改哪個(gè)節(jié)點(diǎn)。
之所以需要通過(guò)算法來(lái)比對(duì)兩個(gè)節(jié)點(diǎn)的差異俗扇,并針對(duì)不同的節(jié)點(diǎn)進(jìn)行更新硝烂,主要是為了性能考慮。
我們完全可以把整個(gè)舊節(jié)點(diǎn)從DOM中刪除铜幽,然后使用最新?tīng)顟B(tài)(state)重新生成一份全新的節(jié)點(diǎn)插入到DOM中滞谢,這種凡是完全是可以實(shí)現(xiàn)功能。
由于我們最終的目的是渲染視圖除抛,所以可以發(fā)現(xiàn)渲染視圖的標(biāo)準(zhǔn)是以vnode(使用最新?tīng)顟B(tài)創(chuàng)建的vnode)來(lái)渲染而不是oldVnode狮杨。
新增節(jié)點(diǎn)
首先,新增節(jié)點(diǎn)的一個(gè)很明顯的場(chǎng)景就是到忽,當(dāng)oldVnode不存在而vnode存在時(shí)橄教,就需要用vnode去生成真實(shí)的DOM并插入到視圖中去。
這通常會(huì)發(fā)生在首次渲染中喘漏。因?yàn)槭状武秩緯r(shí)护蝶,DOM中不存在任何的節(jié)點(diǎn),所以oldVnode是不存在的翩迈。