這會是制約Svelte發展的最大因素么
大家好,我卡頌。
這些年前端框架一直呈螺旋狀發展。
具體來說,很多主流前端框架采用的技術實際上很早就被發明了。比如10年,「細粒度更新」就在Knockout中首創。
新框架的出現一般遵循:
一個新的「主意」 + 現有技術的排列組合
最近2年,最受歡迎的「主意」便是Svelte帶來的「重編譯時」概念了。
這也讓他成為StackOverflow21年開發者報告中最受歡迎的框架。
然而,開源界和工業界可能是兩幅光景:
開發者嘴上說著"哎呦,這個框架不錯哦",等到寫項目時身體卻很誠實的選擇了React。
這也不能怪開發者。畢竟,生態才是前端框架最重要的部分。
本文要講的,就是個很可能制約Svelte生態發展的因素。
從VUE聊起
當初VUE3在技術選型時,有個考慮的點是:
- 要不要移除「虛擬DOM」,擁抱「重編譯時」
「虛擬DOM」的作用是:找到交互造成的UI變化的部分。
但是,VUE3采用「細粒度更新」,理論上只要粒度足夠細,就完全不需要「虛擬DOM」。
通常,依賴「虛擬DOM」的框架,「虛擬DOM」會占據運行時一大半工作量(比如React、VUE)。
如果能移除「虛擬DOM」能帶來如下好處:
打包后的框架代碼體積減少
運行時交互造成UI更新的流程更短
但是,VUE3最終保留了「虛擬DOM」,其中一個很重要的原因是:
- 「虛擬DOM」能彌補「模版語言」的局限
虛擬DOM的優勢比如,當你需要在VUE中實現「布局組件」:
- <Layout level={1}>
- <div>1</div>
- <div>2</div>
- <Layout level={2}>
- <div>33</div>
- <div>44</div>
- </Layout>
- </Layout>
期望的效果是:嵌套在Layout中的結構有不同縮進。
輸出的HTML如下:
- <div class="layout">
- <div class="layout--1">
- <div>1</div>
- <div>2</div>
- <div class="layout">
- <div class="layout--2">
- <div>33</div>
- <div>44</div>
- </div>
- </div>
- </div>
- </div>
這需要用到slot特性。
但是注意這部分,需要根據組件傳入的level prop動態改變:
- <div class="layout--1">
- // ...
- </div>
比如:level = 1對應class="layout--1"。
單純使用「模版語法」,已經沒辦法描述這個特性了。
此時,就需要你手寫「render函數」。
所以,為了編寫復雜組件,VUE為開發者開放了「模版語法」與「手寫render函數」兩條路子。
之所以能有兩條路子,是因為這兩條路最終都通向「虛擬DOM」。
前端框架生態中很重要的一環,便是組件庫的豐富程度了。
為了一個好用的組件庫換框架是常有的事。
所以,為了減少開發者編寫復雜組件的成本,VUE保留了「虛擬DOM」。
Svelte永遠閉上的門
作為和VUE一樣采用「模版語法」的框架,Svelte選擇「重編譯時」道路。
這就意味著他永遠拋棄了「虛擬DOM」,也拋棄了「虛擬DOM」帶來的靈活性。
在討論Render functions的PR[1]中,官方明確表示:
Svelte永遠不會考慮render函數
既然拋棄了「render函數」(以及背后的「虛擬DOM」),那么當編寫復雜組件時,唯一的出路便是:
- 提供更多、更復雜的API以應對復雜場景
比如:對于slot特性,Svelte提供了4個API:
- <slot>
- <slot name="name">
- $$slots
- <slot key={value}>
反觀React,由于極度靈活,壓根沒有對應API。
我們可以大膽的推測,編寫復雜組件的成本:
React < VUE < ... < Svelte
總結
如果一個框架只是概念新奇,會得到一時的關注。
但是,只有在DX(開發者體驗)、UX(用戶體驗)都做到平衡的框架才能在工業界長久存在。
這一點上,Svelte任重道遠。
參考資料
[1]討論Render functions的PR:
https://github.com/sveltejs/svelte/issues/4971