Vue3 的新特性(四) —— 虛擬DOM的底層原理

目錄

前言

Vdom (虛擬dom)憑借著出色的性能成為了目前的主流的前端框架都會(huì)選擇的渲染方案蒜哀。再加上優(yōu)秀的 diff 算法對(duì)它的一步步的優(yōu)化,使框架的價(jià)值得到了極致的體現(xiàn),幾乎成為了我們前端開(kāi)發(fā)必不可少的方案吧碾。

我們已經(jīng)知道颅围,Vue2.x 中的 Vdom 已經(jīng)相當(dāng)出色了粘我,性能非常優(yōu)秀聂薪。不過(guò)令人興奮的是瞭亮,盡管它夠快方仿,但在 Vue3 中還是對(duì) Vdom 進(jìn)行了重寫(xiě),使 Vue3 突破了 Vdom 的性能瓶頸统翩,更快仙蚜!

Vue3 如何重寫(xiě) Vdom

在開(kāi)始介紹之前,先給大家推薦一個(gè)網(wǎng)站:[https://vue-next-template-explorer.netlify.app]

這是 Vue3 官方的演示 Vdom 的示例網(wǎng)站厂汗,本篇文檔也是基于它進(jìn)行演示委粉。

1. 入門(mén)

  • 當(dāng)我們創(chuàng)建一個(gè)這樣的靜態(tài) dom 元素的時(shí)候:

    真實(shí)DOM
  • Vue3 給我們編譯后的 Vdom 是這個(gè)樣子的:

    虛擬dom

看似比較復(fù)雜,實(shí)際上 _createBlock 函數(shù)中才是我們創(chuàng)建的 dom娶桦,從它身上我們可以看出贾节,我們創(chuàng)建了一個(gè) span 元素,內(nèi)容為 “Hello World!”衷畦。這就是 Vdom 最基礎(chǔ)的形式栗涂,在這里我們并不會(huì)感覺(jué)到 Vue3 與 Vue2 有什么不同。

2. patch flag 優(yōu)化靜態(tài)樹(shù)

  • 當(dāng)我們創(chuàng)建了一個(gè)動(dòng)態(tài)的 dom 元素:

    真實(shí)動(dòng)態(tài)dom
  • Vue3 編譯后的 Vdom 是這個(gè)樣子的:

    虛擬動(dòng)態(tài)dom

我們發(fā)現(xiàn)創(chuàng)建動(dòng)態(tài) dom 元素的時(shí)候祈争,Vdom 除了模擬出來(lái)了它的基本信息之外斤程,還給它加了一個(gè)標(biāo)記: 1 /* TEXT */

這個(gè)標(biāo)記就叫做 patch flag(補(bǔ)丁標(biāo)記)

patch flag 的強(qiáng)大之處在于,當(dāng)你的 diff 算法走到 _createBlock 函數(shù)的時(shí)候铛嘱,會(huì)忽略所有的靜態(tài)節(jié)點(diǎn)暖释,只對(duì)有標(biāo)記的動(dòng)態(tài)節(jié)點(diǎn)進(jìn)行對(duì)比袭厂,而且在多層的嵌套下依然有效墨吓。

盡管 JavaScriptVdom 的對(duì)比已經(jīng)非常的快球匕,但是 patch flag 的出現(xiàn)還是讓 Vue3 的 Vdom 的性能得到了很大的提升,尤其是在針對(duì)大組件的時(shí)候帖烘。

3. patch flag 優(yōu)化靜態(tài)屬性

1. 靜態(tài)綁定

  • 當(dāng)我們創(chuàng)建一個(gè)有屬性的元素:

    有屬性的DOM
  • Vue3 編譯后的 Vdom 是這個(gè)樣子的:

    有屬性的Vdom

    讓我們觀察它的 patch flag 亮曹,發(fā)現(xiàn)并沒(méi)有對(duì) id 做特殊的標(biāo)記。是因?yàn)?dom 元素的靜態(tài)屬性在渲染的時(shí)候就已經(jīng)創(chuàng)建了秘症,并且是不會(huì)變動(dòng)的照卦,在后面進(jìn)行更新的時(shí)候,diff 算法是不會(huì)去管它的乡摹。

2. 動(dòng)態(tài)綁定

  • 當(dāng)我們創(chuàng)建一個(gè)屬性是動(dòng)態(tài)綁定的元素:

    動(dòng)態(tài)屬性元素
  • Vue3 編譯后的 Vdom 是這個(gè)樣子的:

    動(dòng)態(tài)屬性元素Vdom

    再觀察它的 patch flag 役耕,會(huì)發(fā)現(xiàn)變成了 9 /* TEXT, PROPS */,而且后邊多了一個(gè)數(shù)組 ["id"]

    這里的 patch flag 中的注釋的內(nèi)容告訴我們聪廉,這一個(gè) dom 元素不止有內(nèi)容 TEXT 會(huì)變化瞬痘,它的屬性 PROPS 也會(huì)變化。而后邊的數(shù)組中的內(nèi)容則是有可能發(fā)生變化的屬性板熊。

看到這里框全,我們就會(huì)明白 Vue3 實(shí)際做的事情了。

Vue3 在 Vdom 的更新時(shí)干签,只會(huì)關(guān)注它有變化的部分津辩。這樣的優(yōu)化使 Vue3 既跳出了 Vdom 的性能瓶頸,又依然保留了可以手寫(xiě) render function 的靈活性容劳。相當(dāng)于 Vue3 既有 react 的靈活性喘沿,又有基于模板的性能保證〗叻罚——尤雨溪

4. 靜態(tài)提升

剛剛我們提到 Vue3 突破 Vdom 的性能瓶頸的方式是蚜印,只關(guān)注它有變化的部分。而在更新時(shí)具體是怎么做的呢娶视?

具體的做法就是 靜態(tài)樹(shù)的提升靜態(tài)屬性的提升

  • 我們創(chuàng)建若干的 dom 元素:

    dom元素
  • 靜態(tài)提升之后:

    靜態(tài)提升后的dom元素

    我們已經(jīng)知道處理后的 Vdom 都在 _createBlock 函數(shù)之中晒哄,而觀察結(jié)果我們發(fā)現(xiàn),所有的靜態(tài)元素都被放在了 _createBlock 函數(shù)之外了肪获,也就是說(shuō)他們只會(huì)在頁(yè)面初始的時(shí)候被渲染一次寝凌,而在更新的時(shí)候,靜態(tài)元素是不予搭理的孝赫。

    這個(gè)優(yōu)化就是 Vue3 的 靜態(tài)提升

5. 事件偵聽(tīng)器緩存

了解 react 的同學(xué)都知道较木,在我們使用 react 時(shí),對(duì)其性能優(yōu)化的其中一點(diǎn)就是將偵聽(tīng)方法手動(dòng)進(jìn)行緩存青柄,避免更新組件時(shí)被多次重新創(chuàng)建伐债。而 Vue3 直接替我們做了這一點(diǎn)

  • 創(chuàng)建一個(gè)帶有事件偵聽(tīng)的元素

    有事件偵聽(tīng)的dom
  • 沒(méi)有進(jìn)行事件偵聽(tīng)器緩存的 Vdom

    沒(méi)有事件偵聽(tīng)緩存的Vdom

    在這里的 _createBlock 函數(shù)中就是這個(gè)元素的 Vdom 結(jié)構(gòu)预侯。觀察高亮的地方,發(fā)現(xiàn) onClick 函數(shù)以變量的形式存在峰锁。

  • 進(jìn)行事件偵聽(tīng)器緩存后的 Vdom

    有事件偵聽(tīng)緩存的Vdom

    觀察高亮的那一行萎馅,我們發(fā)現(xiàn) onClick 函數(shù)的儲(chǔ)存位置變成了緩存的形式。也就是說(shuō) 當(dāng)你的頁(yè)面在不斷的更新的時(shí)候虹蒋,你的事件偵聽(tīng)器并不會(huì)重復(fù)地銷(xiāo)毀再創(chuàng)建糜芳,而是以緩存的形式存在,這使 Vue3 在性能方面又有了一個(gè)出彩的地方魄衅。

    另外峭竣,Vue3 在 @click 中,直接手寫(xiě)內(nèi)聯(lián)函數(shù)也會(huì)被緩存起來(lái)晃虫,這一點(diǎn)是 react 做不到的皆撩。再加上 在 Vue3 中父組件的更新并不會(huì)直接觸發(fā)子組件的更新,使得事件偵聽(tīng)器緩存在組件的層面可以提現(xiàn)出來(lái)更高的價(jià)值哲银。

其他

以后的章節(jié)

總結(jié)

Vue3 在性能優(yōu)化上的小方面扛吞,直接在編譯的時(shí)候給你做到最好,這是它最有價(jià)值的地方盘榨。想必看完這些東西喻粹,你一定更期待 Vue3 的發(fā)布了!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末草巡,一起剝皮案震驚了整個(gè)濱河市守呜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌山憨,老刑警劉巖查乒,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異郁竟,居然都是意外死亡玛迄,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)棚亩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)蓖议,“玉大人,你說(shuō)我怎么就攤上這事讥蟆±障海” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵瘸彤,是天一觀的道長(zhǎng)修然。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么愕宋? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任玻靡,我火速辦了婚禮,結(jié)果婚禮上中贝,老公的妹妹穿的比我還像新娘囤捻。我一直安慰自己,他們只是感情好雄妥,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布最蕾。 她就那樣靜靜地躺著依溯,像睡著了一般老厌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上黎炉,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天枝秤,我揣著相機(jī)與錄音,去河邊找鬼慷嗜。 笑死淀弹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的庆械。 我是一名探鬼主播薇溃,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缭乘!你這毒婦竟也來(lái)了沐序?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤堕绩,失蹤者是張志新(化名)和其女友劉穎策幼,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體奴紧,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡特姐,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了黍氮。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唐含。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沫浆,靈堂內(nèi)的尸體忽然破棺而出捷枯,到底是詐尸還是另有隱情,我是刑警寧澤件缸,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布铜靶,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏争剿。R本人自食惡果不足惜已艰,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蚕苇。 院中可真熱鬧哩掺,春花似錦、人聲如沸涩笤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蹬碧。三九已至舱禽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間恩沽,已是汗流浹背誊稚。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留罗心,地道東北人里伯。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像渤闷,于是被迫代替她去往敵國(guó)和親疾瓮。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355