Vue 想要拋棄虛擬 DOM 了?!

語言: CN / TW / HK

最近 Vue 在美國舉辦了 Vue Conf 2022,不過可惜的是在國內並未掀起任何的波瀾,於是我來試試能不能一石激起千層浪,因為尤雨溪在 Vue Conf 上說他們正在探索一種新的編譯策略。

流行趨勢 

不知大家發現沒有,自從 2021 年以來,無虛擬 DOM 框架/庫/編譯器獲得了極大的矚目,最為典型的兩個專案:

  • Svelte

  • Solid.js

我們來看看他倆究竟有多勇:

(來自https://www.tecla.io/blog/top-js-frameworks)

可以看到 Svelte 去年一年在 GitHub 上增長的 Star 接近 Vue ,甚至力壓老牌經典框架 Angular

再來看看這個:

滿意度甚至超越 React Vue ,(吐槽: Angular 這滿意度趨勢…)

感興趣程度同樣霸榜,只不過這回剛好反過來: Svelte 力壓 SolidVue 力壓 React (越來越多的人對 Vue 感興趣了哈)。 Angular 頹勢已顯,氣數已盡了?別擔心!下一個選項(Usage)讓 Angular 來告訴你,什麼叫你大爺永遠是你大爺:

奇怪,感覺自己身邊明明沒那麼多人用 Angular ,怎麼肥四?這是因為調查物件主要以歐美地區為主(尤其美國):

母語為英語的人佔多數:

年輕人為主:

這就很完美的解釋了為什麼 SolidSvelte 的受歡迎程度會那麼高,年輕啊!折騰啊!你要是五六十歲了(在中國應該沒有這個歲數的程式設計師了吧)你也不願意折騰那些亂七八糟的。

年輕不代表是新手,還是有相當一部分有經驗的開發者參與調查的。

資料來源:https://2021.stateofjs.com/en-US/libraries/front-end-frameworks/

不過這些資料還不能證明 Svelte Solid 已經成為流行框架\庫\編譯器了,有相當一部分叫好不叫座的,我們來看看 npm 的資料:

哎呀!暴露了暴露了,再來看看 Google 搜尋量:

可以看到三大框架依然是主流哈,而且 Vue Angular 的差距已經越來越小了,當然還因為有股神祕的東方力量遮蔽掉了大部分去 Google 搜尋 Vue 的,不然我相信 Vue 的資料一定可以超越 Angular 的。

資料來源自https://trends.google.com/trends/explore?cat=31&date=today%205-y&q=React%20javascript,Vue%20javascript,Angular%20javascript,Solid.js%20javascript,Svelte%20javascript

沒想到對 Svelte 最感興趣的居然是韓國人!雖然三大框架 YYDS ,但作為後起之秀並且在沒有明顯優勢的情況下(綜合情況,光寫個 Hello World 確實誰也比不過 Svelte )依然能夠從三大框架嘴裡分一杯小小的羹,並且還能夠獲得如此巨大的關注度,那就證明無虛擬DOM的趨勢已經悄然興起了。

為什麼這玩意會成為一種趨勢呢?有啥好處?好處就是效能!

什麼?虛擬 DOM 不就是為了提升效能的嗎?!是也不是,推薦讀一下這篇:

[0]《網上都說操作真實 DOM 慢,但測試結果卻比 React 更快,為什麼?》

他們會火不是沒有原因的,我們來看看他倆的效能:

可以用 傲視群雄 這四個字來形容了 Vue 之前一直以高效能為傲,但被人超了怎麼可能會甘心?畢竟 Vue React 不一樣,當資料更新時 Vue 是知道該更新哪個元件的, React 不知道所以它只能用 diff 演算法,沒有虛擬 DOM 根本不行。那 Vue 幹嘛也要來一個虛擬 DOM 呢?尤雨溪也是這麼想的!

其實他早就有過放棄虛擬 DOM 的想法了:在尤雨溪發表的《Vue3的設計過程》(翻譯版)一文中,尤大說:一種選擇是放棄虛擬   DOM   並直接生成命令式   DOM   操作,但這將消除直接編寫虛擬  DOM   渲染功能的能力,我們發現 這對高階使用者和庫作者非常有價值。

那時候 Vue3 還沒釋出呢, Vue3 createRenderer 就是利用虛擬 DOM 來實現跨平臺的,但成天老是跨平臺跨平臺的,我們平時開發業務又有多少跨平臺專案呢?

現在追求的就是一個輕量級,沒有了虛擬 DOM 就沒有了 Diff 演算法,不僅可以不用執行一些無謂的計算,而且打包出來的體積那可真是輕上加輕啊!它不香嗎?

但也不能完全放棄虛擬 DOM 啊,一方面虛擬 DOM 還是有它大展巨集圖的場景的。另一方面你直接把虛擬 DOM 刪了,那些庫怎麼辦?它們有多少是依賴虛擬 DOM API 的呢?有多少元件庫用的是 jsx 呢:

[1] 《為什麼 Vue3 的元件庫都在使用 jsx/tsx?》

去掉了虛擬 DOM 的話,那些元件庫是不是就用不了了呢?那咱們可以搞個模式出來嘛!

無虛擬DOM模式

首先咱們先把尤大在釋出會上說的話(重點部分)翻譯下,為了節省篇幅不重點的地方就不貼上來了:

主要的事情就是:我們想要探索一種新的編譯策略

我們都知道 Vue 是一個基於模板的框架,即使你能用 jsx 能用虛擬 DOM ,但大多數使用者還是會用 template 模板。

(挨個截圖太麻煩了我就不截了,還浪費篇幅,我就直接寫翻譯了,感興趣的話可以點進去 視訊連結 [2] 看)

由於 Vue 的大部分使用者都用單檔案元件來寫程式碼,所以我們其實是有機會把元件編譯成原生JS、CSS的。所以編譯的這個步驟是有機會能讓 Vue 變成一個超級編譯器的!這將會很有趣,所以我們想要探索一下新的編譯策略,這也是受到了 Solid.js 的啟發。新的編譯策略可以把 template 模板編譯成命令式的 DOM 操作+響應式的 setup 繫結以代替虛擬 DOM render 函式。所以想象一下,當我們寫了一個這樣的元件:

(此處省略一些廢話:這是 script setup 語法、看這裡有個 button 按鈕、我們給按鈕繫結一個響應式的值之類的話)

我們生成的將會是這樣的程式碼,生成出來的程式碼量非常少,目前的想法是我們過一遍虛擬 DOM 樹然後生成真實 DOM 的操作。我們會在編譯期分析 template 模板裡的 HTML 的結構並將其字串化:

為了能讓打包出來的內容最小化,去掉了結束標籤以及各種繫結的屬性。然後再生成一個 cloneNode

通過分析得出哪些屬性是響應式的,把它們都放在 effect 裡,再繫結事件,全部都是非常好理解的 DOM 操作:

(這不比 Svelte 生成出來的那一大坨好多了?)

兩種模式

這裡的兩種模式指的並不是 虛擬DOM模式 無虛擬DOM模式 這兩種模式,而是 無虛擬DOM模式 下還可以繼續再往下細分出來兩種模式:

元件模式

比方說你現在手裡已經有了長期維護的 Vue3 專案,你要是直接換成 無虛擬DOM模式 那肯定是要出問題的,所以可以採用元件模式來精確控制哪些元件不需要虛擬 DOM

比方說你的專案中採用了尤大推薦的 naive-ui 這個元件庫,我們開啟一個比較常用的元件 Button 來看一下:

tsx 結尾,那虛擬 DOM 算是沒跑了。不過 tsx 也照樣可以給改成生成真實 DOM 的函式啊, solid.js 不就是這麼幹的嗎?其實理論上來說確實是可以做到的,我們點進去再看一眼:

這裡用到了 h 函式,這個函式是專門用來生成虛擬 DOM 的,假如你把專案全部換成了 無虛擬DOM模式 同時這些庫還沒來得及跟進的話,那肯定是不行的。

所以你可以控制,你哪個元件裡沒用這個元件庫,你再給這個元件單獨的一個編譯策略( 無虛擬DOM模式 )。

既然有元件級的那就肯定有應用級的,比方說你想開發一個 UI 高度定製化的 H5 活動頁。

一般來說這樣的頁面不會用元件庫,都是自己寫樣式。另一方面這種活動頁當然是越小越好,越快越好啦!那麼此時你就可以採用全域性 無虛擬DOM模式

怎麼感覺這是在搶 Svelte 飯碗呢?我看技術論壇已經有人分享了自己用 Svelte 來開發一些小頁面的文章了,這回再有什麼效能跑分之類的評測 Vue 應該不會再輸給 Svelte 了(看情況,元件越少 Svelte 越佔優,反之則 Vue 佔優)

機遇與挑戰

最近前端可謂是越來越捲了,你要是去面試稍微高階點的崗位的話,估計很可能會問你 Vue 怎麼編譯的兩種模式了(即使你並不感興趣)。

但我發現很多人對自己做一款元件庫非常感興趣,從文章列表裡看一下究竟有多少元件庫相關的文章就能夠一探究竟了。而且很多教大家搭建元件庫的文章也是點贊量非常高,還有很多文章推薦自己做出來的元件庫。

只可惜大部分個人做的元件庫都是孤芳自賞,沒幾個人用。一方面的個人開發者可能隨時刪庫跑路,不穩定。誰知道你寫的那玩意有多少 bug 呢?另一方面大家也更願意用 Star 非常多的元件庫,證明其穩定。

所以大家如果想從主流元件庫那裡分一杯羹的話還是非常困難的。那現在這個無虛擬 DOM 模式是不是就是一個千載難逢的大好時機?不過我個人依然感覺希望不大,因為那些主流元件庫肯定會立馬跟進,搞一款無虛擬 DOM 適配版。

不過不管怎麼說,我對這個實驗性特性還是非常期待的。因為這個編譯策略編譯成 web components 很可能會是一個非常不錯的選擇,總之,期待 無虛擬DOM 的到來!

文章連結:

[0]: https://www.zhihu.com/question/31809713/answer/53544875

[1]: https://www.zhihu.com/question/436260027/answer/1647182157

[2]:https://www.bilibili.com/video/BV12S4y1e7pn?p=1&share_medium=android&share_plat=android&share_session_id=4e2c7597-7fa7-4e0a-a098-5e0aa675b035&share_source=WEIXIN&share_tag=s_i&timestamp=1655041421&unique_k=nLvKgzv&vd_source=3490d817b36fc42ec9a252b6cd0d6baf

- EOF -

覺得本文對你有幫助?請分享給更多人

關注「大前端技術之路」加星標,提升前端技能

點贊和在看就是最大的支援 :heart: