新聞中心
前言
大家好我是愛(ài)分享的老前端羊村長(zhǎng),國(guó)外最近兩年涌現(xiàn)兩個(gè)新銳框架Svelte和Solid,大家可能忙工作沒(méi)太關(guān)注,但是t它們大有后來(lái)居上的意思。來(lái)看一下github的star數(shù)量感受一下:

成都創(chuàng)新互聯(lián)是專業(yè)的衡南網(wǎng)站建設(shè)公司,衡南接單;提供成都網(wǎng)站設(shè)計(jì)、網(wǎng)站建設(shè),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行衡南網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
7月掘金開(kāi)發(fā)者大會(huì)上,Vue作者尤雨溪在直播分享中多次提到SolidJS和Svelte。到底是什么原因讓開(kāi)發(fā)者們?nèi)绱讼矏?ài)?又是什么原因讓尤大如此關(guān)注它們?我們到底要不要花時(shí)間研究學(xué)習(xí)它們?
文本將帶大家體驗(yàn)這兩款框架的魅力,并發(fā)表一些個(gè)人看法,歡迎小伙伴們拍磚!
對(duì)應(yīng)的學(xué)習(xí)群已經(jīng)建立起來(lái),我將陸續(xù)發(fā)布學(xué)習(xí)文章和視頻,歡迎感興趣的小伙伴加入: 關(guān)注公眾號(hào)“村長(zhǎng)學(xué)前端”,分別回復(fù)“svelte”和“solid”即可。
相同的開(kāi)發(fā)范式
應(yīng)該說(shuō)最近3年前端最流行的開(kāi)發(fā)范式非React Hooks莫屬,React Hooks徹底取代了Class Components,Vue3也從最初的Class風(fēng)格最終確定為類似的Composition API,今天要討論的兩位主角也不例外均是函數(shù)風(fēng)格。應(yīng)該說(shuō),是React Hooks引領(lǐng)創(chuàng)新,啟發(fā)了眾多框架啟用新范式,但青出于藍(lán),相似的同時(shí)解決了React Hooks各種問(wèn)題。
這里出現(xiàn)三位競(jìng)爭(zhēng)選手:Vue3、Svelte和SolidJS。Vue3大家都很熟悉就不過(guò)多贅述,這里我們主要體驗(yàn)一下Svelte和SolidJS如何做組件邏輯表達(dá)和邏輯復(fù)用。
組件邏輯表達(dá)
Svelte3
作者Rich Harris曾說(shuō)過(guò)Svelte的組件編譯邏輯是由React Hooks啟發(fā)而來(lái)。然而,由于Svelte 組件構(gòu)建在 HTML 之上,所以她看起來(lái)更像Vue。同時(shí)她更加優(yōu)雅了,我們沒(méi)有看到諸如let count = ref(0)這樣的響應(yīng)式聲明,當(dāng)然也不需要count.value++。我們也沒(méi)看到template這樣的標(biāo)簽,就好像我們?cè)趯?xiě)HTML頁(yè)面一般純粹!
下面我們用Svelte編寫(xiě)一個(gè)counter案例,Counter.svelte:
作為一個(gè)Vuer,你會(huì)為了這些改變學(xué)習(xí)Svelte嗎? 顯然是不夠的!我好不容易已經(jīng)習(xí)慣了ref和.value,現(xiàn)在感覺(jué)也沒(méi)什么大不了的。 但是作為一個(gè)新人,如果第一眼看到Svelte,我一定會(huì)愛(ài)上她! 她真的太優(yōu)雅了,一見(jiàn)鐘情的感覺(jué)!
Solid
尤大這樣描述SolidJS:語(yǔ)法與React相似,實(shí)現(xiàn)與Composition API相似。我們同樣體驗(yàn)一下她的魅力!下面是Solid版的Counter案例:
// Counter.jsx
import { createSignal } from "solid-js";
export default function Counter() {
const [count, setCount] = createSignal(0);
const increment = () => {
setCount(count() + 1);
};
return ;
}
作為一個(gè)Reacter,你發(fā)現(xiàn)了什么變化?
- useState()?變成了createSignal()
- count?變成了count()
你會(huì)為了這些變化學(xué)習(xí)SolidJS嗎?顯然不會(huì),一個(gè)東西換個(gè)寫(xiě)法沒(méi)有什么意義。 作為一個(gè)新人你會(huì)喜歡SolidJS嗎?可能也不會(huì),這代碼看起來(lái)不太容易理解,市面上也沒(méi)有招Solid程序員呀,與其這樣還不如直接學(xué)React!
暫時(shí)排名
看到這里,我根據(jù)個(gè)人感覺(jué)做個(gè)暫時(shí)的排名
老鳥(niǎo)榜:Vue3 = React > Svelte3 > Solid
老鳥(niǎo):不要跟我說(shuō)什么react、angular、vue,老夫?qū)懘a就用jQuery!
菜鳥(niǎo)榜:Vue3 > Svelte3 > React > Solid
菜鳥(niǎo):大哥們哪個(gè)框架最簡(jiǎn)單?國(guó)內(nèi)是不是招Vue的最多?就它了!
基于依賴追蹤的范式
尤大曾在直播分享中談到React Hooks存在一些開(kāi)發(fā)體驗(yàn)問(wèn)題,例如手動(dòng)添加依賴、條件語(yǔ)句限制、過(guò)期閉包等。
不約而同的,各大新銳勢(shì)力在依賴管理這塊各顯神通,均通過(guò)各種手段做到了依賴的自動(dòng)收集管理,這讓開(kāi)發(fā)體驗(yàn)提升了一個(gè)檔次。
SolidJS
我們現(xiàn)在給Counter添加一個(gè)功能:如果count發(fā)生變化,控制臺(tái)打印輸出。
可以看到我們不需要手動(dòng)指定依賴項(xiàng)即可追蹤變化。
// 導(dǎo)入createEffect
import { createEffect, createSignal } from "solid-js";
export default function Counter() {
const [count, setCount] = createSignal(0);
// createEffect用于創(chuàng)建副作用,Solid幫我們追蹤依賴項(xiàng)count
createEffect(() => {
console.log('count: ' + count());
})
const increment = () => {
setCount(count() + 1);
};
return ;
}
這里就體現(xiàn)了SolidJS和React之間的不同點(diǎn),開(kāi)發(fā)者不再需要操心依賴項(xiàng):
// 同樣的功能,`React`要指定依賴項(xiàng)
useEffect(() => {
setCount(count + 1);
}, [count])
這就是尤大說(shuō)的類似React語(yǔ)法,實(shí)現(xiàn)類似Vue Composition API。 大家不要小看這些變化,除了心智負(fù)擔(dān)影響開(kāi)發(fā)體驗(yàn)之外,有時(shí)還會(huì)不小心寫(xiě)出隱藏bug。
我想這是國(guó)外不少Reacter轉(zhuǎn)投Solid的原因之一。
Vue3
作為對(duì)比,我們拉出Vue給大家看看
這里看起來(lái)確實(shí)和Solid非常相似,定義響應(yīng)式數(shù)據(jù),添加副作用函數(shù),只不過(guò)Solid是讀寫(xiě)分離的。
尤大總結(jié)的其他共同點(diǎn)
- 一次調(diào)用,符合原生JS直覺(jué)
- 自動(dòng)追蹤依賴,無(wú)需手動(dòng)聲明
- 引用穩(wěn)定,無(wú)需useCallback
Svelte3
Svelte響應(yīng)式系統(tǒng)基于編譯,因此也不需要做依賴追蹤,但是作為用戶我們只關(guān)心怎么寫(xiě)代碼。
下面我們看一下Svelte的寫(xiě)法:
let count = 0
// 副作用寫(xiě)在'$:'后面
$: console.log(count)
const increment = () => {
count += 1
}
依然是最簡(jiǎn)潔的那一個(gè),一個(gè)$就解決問(wèn)題! 我對(duì)Svelte的喜愛(ài)又增加了~
暫時(shí)排名
看到這里,我的排名發(fā)生了一些變化:Svelte和Vue在菜鳥(niǎo)榜平起平坐!
老鳥(niǎo)榜:Vue3 = React > Svelte3 > Solid
老鳥(niǎo):不要跟我說(shuō)什么react、angular、vue,老夫?qū)懘a就用jQuery!
菜鳥(niǎo)榜:Vue3 = Svelte3 > Solid > React
菜鳥(niǎo):woc太NB了,就選Svelte了!
基于編譯的響應(yīng)式系統(tǒng)
為了能夠盡可能提升開(kāi)發(fā)體驗(yàn),大家紛紛祭出大招,開(kāi)始在編譯階段做文章,比如各種基于編譯的響應(yīng)式方案:Svelte、Vue Reactivity Transform、solid labels
Svelte
輪子哥Harris在Svelte上充分利用編譯期能力,例如下面代碼,一個(gè)簡(jiǎn)單$符號(hào)就可以生成副作用代碼
let count = 0
// 編譯器發(fā)現(xiàn)`$:`,就會(huì)把后面代碼作為count的副作用
$: console.log(count)
const increment = () => {
count += 1
}
這個(gè)看起來(lái)確實(shí)很NB,作為新手我不需要學(xué)習(xí)響應(yīng)式機(jī)制和相關(guān)API,非常簡(jiǎn)潔。
但是,簡(jiǎn)潔是有代價(jià)的,關(guān)于這點(diǎn)尤大層發(fā)出大招棒打Svelte,我們來(lái)看看他說(shuō)的有沒(méi)有道理:
- Svelte組件內(nèi)才能使用$:語(yǔ)法,組件外需要另一套不同的API
- $:只能在頂層作用域內(nèi)使用,不可在函數(shù)內(nèi)用
Svelte Stores API
這個(gè)stores API就是前面尤大提到的“Svelte組件內(nèi)才能用$:語(yǔ)法”槽點(diǎn)中提到的另一套不同API,我們來(lái)體驗(yàn)一下。
比如我們將count提到JS中去做狀態(tài)共享給不同組件,使用Svelte我需要這樣做:
import { writable } from 'svelte/store';
// 使用writeable()創(chuàng)建一個(gè)可寫(xiě)的count
export const count = writable(0);Vue中的話我會(huì)這樣做:
import { ref } from 'vue'
export function useCount() {
// 使用ref()創(chuàng)建一個(gè)響應(yīng)式count
const count = ref(0)
return { count }
}這里Vue實(shí)現(xiàn)保持了組件內(nèi)編寫(xiě)的一致性,確實(shí)很好。不過(guò)作為槽點(diǎn)噴Svelte我覺(jué)得沒(méi)道理,Svelte只是把學(xué)習(xí)一個(gè)API的時(shí)間推后了一點(diǎn),我不學(xué)習(xí)Composition API不是也寫(xiě)不出這個(gè)Vue代碼嘛。另外如果需要全局狀態(tài)管理,我還是要學(xué)一個(gè)Vuex語(yǔ)法,并不能讓我少學(xué)點(diǎn)。
響應(yīng)式限制
另一個(gè)槽點(diǎn)是:$:只能在頂層作用域內(nèi)使用,不可在函數(shù)內(nèi)用。
我想尤大想要的是能夠?qū)⑦@個(gè)邏輯提取到函數(shù)內(nèi),這樣可以復(fù)用這段邏輯。
比如利用Composition API,我們可以:
function useCount() {
const count = ref(0)
watchEffect(() => {
console.log(`the count is ${count.value}`);
alert(`the count is ${count.value}`);
})
return {count}
}但是我們不能像下面這樣:
function useCount() {
$: {
console.log(`the count is ${count}`);
alert(`the count is ${count}`);
}
}或者:
$: useCount()
function useCount() {
console.log(`the count is ${count}`);
alert(`the count is ${count}`);
}
這個(gè)限制性問(wèn)題其實(shí)還是上面的Stores API問(wèn)題,我們利用Stores API就可以完成提取,只是我們失去了$:這種一致性寫(xiě)法。
export function useCount() {
const count = writable(0);
count.subscribe(value => {
console.log(`the count is ${count}`);
alert(`the count is ${count}`);
});
return {count}
}Vue Reactivity Transform
Vue3中引入Ref之后,.value的心智負(fù)擔(dān)也一直被人詬病,尤大也想出了很多解決方案。實(shí)驗(yàn)性質(zhì)的新特性Vue Reactivity Transform就是其中之一。我們可以像下面這樣寫(xiě)代碼:
let count = $ref(0) // 使用$ref聲明一個(gè)響應(yīng)式對(duì)象
watchEffect(() => console.log(count)) // 使用時(shí)可以不需要.value
count++ // 使用時(shí)可以不需要.value
相關(guān)文檔: https://vuejs.org/guide/extras/reactivity-transform.html#refs-vs-reactive-variables
這被小右稱為更普適方案,沒(méi)有以上Svelte中的限制。使用起來(lái)確實(shí)不錯(cuò)~看起來(lái)大家還是蠻支持這個(gè)方案的,期待轉(zhuǎn)正!
Solid-labels
前面我們看到solid中使用類react hooks風(fēng)格API,個(gè)人認(rèn)為有以下問(wèn)題:
- 這組API不符合原生JS直覺(jué),比如我感覺(jué)count是個(gè)值,不應(yīng)該作為函數(shù)調(diào)用,修改時(shí)也希望直接賦值。
- 另外總是需要導(dǎo)入solid提供的utilities
import { createEffect, createSignal } from "solid-js"
// ...
createEffect(() => {
// 使用時(shí)需要加上括號(hào):count()
console.log('count: ' + count());
})
// 修改時(shí)需要調(diào)用setXX方法
setCount(count() + 1);那使用solid-labels會(huì)怎樣呢?下面看一下之前的Counter例子使用solid-labels實(shí)現(xiàn):
// $signal()創(chuàng)建響應(yīng)式數(shù)據(jù)
let count = $signal(0)
// $effect()添加副作用,直接調(diào)用count
$effect(() => console.log(count))
// 直接修改count
count++
利用插件同樣實(shí)現(xiàn)了更加簡(jiǎn)潔、更符合JS直覺(jué)的語(yǔ)法,還不用導(dǎo)入solid的工具方法,贊!
項(xiàng)目地址:https://github.com/LXSMNSYC/solid-labels
暫時(shí)排名
可以說(shuō),大家都在利用編譯或轉(zhuǎn)譯的方式簡(jiǎn)化API,提升開(kāi)發(fā)體驗(yàn),而且都非常的簡(jiǎn)潔、優(yōu)雅,同時(shí)各有特點(diǎn):
- Vue Reactivity Transform和Solid-labels這樣的屬于上下文無(wú)關(guān)的統(tǒng)一模型。優(yōu)勢(shì)是重構(gòu)和優(yōu)化,代價(jià)是初期的上手成本。
- Svelte屬于上下文受限模型,優(yōu)勢(shì)是上手成本低,不需要了解響應(yīng)式的實(shí)現(xiàn)機(jī)制。
這一局我感覺(jué)沒(méi)有勝出者,都很優(yōu)秀。因此,我的排名沒(méi)有變化!
老鳥(niǎo)榜:Vue3 = React > Svelte3 > Solid
老鳥(niǎo):不要跟我說(shuō)什么react、angular、vue,老夫?qū)懘a就用jQuery!
菜鳥(niǎo)榜:Vue3 = Svelte3 > Solid > React
菜鳥(niǎo):woc太NB了,我也不知道該選啥!
基于編譯的運(yùn)行時(shí)優(yōu)化
同樣,利用編譯期能力,大家都可以做到極致的優(yōu)化,達(dá)到最佳的性能表現(xiàn)!
但是這里Svelte和Solid就和Vue3走上了完全不同的道路,我們稱之為無(wú)虛擬DOM。什么意思哪?也就是它們均放棄了React開(kāi)啟的流行了10年之久的虛擬DOM方案,并且在性能表現(xiàn)上更是達(dá)到了登峰造極的地步!
下面大家跟隨村長(zhǎng)一起來(lái)一睹究竟!
不同策略對(duì)性能的影響
上面說(shuō)Svelte和Solid通過(guò)放棄虛擬DOM達(dá)到了接近原生DOM的優(yōu)秀性能表現(xiàn),尤其Solid輕松超過(guò)vue3,遠(yuǎn)超react。連尤大都感慨:Solid性能真是NB!
我們一起來(lái)看一下性能統(tǒng)計(jì)圖,這是我9月21日重新生成的:
不是說(shuō)虛擬DOM會(huì)帶來(lái)性能提升嗎?這個(gè)確實(shí)是面試題八股文的答案,但是其實(shí)尤大早就在知乎上回答過(guò)這個(gè)問(wèn)題,大家可以去看原文:
網(wǎng)上都說(shuō)操作真實(shí) DOM 慢,但測(cè)試結(jié)果卻比 React 更快,為什么?
那也就是說(shuō),利用編譯或轉(zhuǎn)譯能力,Svelte和Solid最終都生成了直接操作DOM的更新函數(shù),雖說(shuō)兩者實(shí)現(xiàn)細(xì)節(jié)不甚相同,但是最終都做到了魚(yú)和熊掌兼得的效果,即提升開(kāi)發(fā)效率,又保證性能表現(xiàn)。
針對(duì)這一點(diǎn),尤大又祭出新活,就是所謂的Vapor模式,也就是說(shuō)用戶未來(lái)在使用Vue3時(shí)可以指定某個(gè)組件使用DOM方式編譯結(jié)果,從而提升性能表現(xiàn)。關(guān)于這點(diǎn),我覺(jué)得尤大純屬被帶節(jié)奏,增加了使用復(fù)雜性不說(shuō),大部分場(chǎng)景下收益并不明顯,兩個(gè)新銳在這里飆車,那是想標(biāo)新立異,吸引用戶注意力,現(xiàn)代Web開(kāi)發(fā)中的瓶頸從來(lái)都不是性能而是開(kāi)發(fā)效率和可維護(hù)性。
所以雖說(shuō)數(shù)據(jù)上看起來(lái)不錯(cuò),但我并不認(rèn)為這是什么很大的亮點(diǎn),因此咱們排名依然不變!
老鳥(niǎo)榜:Vue3 = React > Svelte3 > Solid
老鳥(niǎo):不要跟我說(shuō)什么react、angular、vue,老夫?qū)懘a就用jQuery!
菜鳥(niǎo)榜:Vue3 = Svelte3 > Solid > React
菜鳥(niǎo):woc太NB了,我也不知道該選啥!
不同策略對(duì)生成代碼量的影響
最后,我們?cè)偬接懸幌氯齻€(gè)框架在最終生成代碼量上的表現(xiàn)。下面圖片來(lái)自尤大直播中原圖:
可見(jiàn),Svelte和Solid由于不需要虛擬DOM相關(guān)的運(yùn)行時(shí)代碼,在起步階段和Vue比有一QQ差距;但在15個(gè)組件這個(gè)關(guān)鍵節(jié)點(diǎn)之后,我們發(fā)現(xiàn)Svelte打包體積開(kāi)始快速攀升,而Solid和Vue增長(zhǎng)非常平緩,可以說(shuō)并駕齊驅(qū)。
這里我可以說(shuō),如果你特別在意執(zhí)行速度和打包體積,比如一些移動(dòng)端的h5頁(yè)面,那看起來(lái)Solid是你的不二之選。
那Svelte呢?考慮到優(yōu)秀的開(kāi)發(fā)體驗(yàn)和整體性能,只要不是規(guī)模很大的項(xiàng)目應(yīng)該都能勝任。
這里很抱歉我沒(méi)有去打個(gè)包給大家看看結(jié)果,那主要是因?yàn)槲矣X(jué)得我們業(yè)務(wù)代碼多那么幾k,少那么幾k,在現(xiàn)在這個(gè)網(wǎng)絡(luò)條件下根本無(wú)足輕重!
總結(jié)
到了激動(dòng)人心的總結(jié)時(shí)刻,在我心中到底這倆框架值得花時(shí)間學(xué)習(xí)嗎?
值得!
存在必有道理,Svelte和Solid在國(guó)外那么受歡迎不是沒(méi)有原因的,能在內(nèi)卷的前端框架市場(chǎng)殺出一條血路,占據(jù)一席之地,相信必有適合它們的應(yīng)用場(chǎng)景和優(yōu)點(diǎn)。
當(dāng)前文章:后起之秀Svelte和Solid值得花時(shí)間學(xué)習(xí)嗎
轉(zhuǎn)載來(lái)源:http://m.fisionsoft.com.cn/article/cccsjde.html


咨詢
建站咨詢
