淺析Svelte介紹了解、如何看待 svelte 這個前端框架、svelte評測結論(存在一個閾值大小優勢消失、適用簡單應用場景又想要數據驅動方式)


一、Svelte 介紹

  Svelte 是一種全新的構建用戶界面的方法。傳統框架如 React 和 Vue 在瀏覽器中需要做大量的工作,而 Svelte 將這些工作放到構建應用程序的編譯階段來處理

  與使用虛擬(virtual)DOM 差異對比不同。Svelte 編寫的代碼在應用程序的狀態更改時就能像做外科手術一樣更新 DOM。

  Svelte 中文文檔:https://www.sveltejs.cn/tutorial/basics

1、什么是 Svelte?

  Svelte 是一個構建 web 應用程序的工具。

  Svelte 與諸如 React 和 Vue 等 JavaScript 框架類似,都懷揣着一顆讓構建交互式用戶界面變得更容易的心。

  但是有一個關鍵的區別:Svelte 在 構建/編譯階段 將你的應用程序轉換為理想的 JavaScript 應用,而不是在 運行階段 解釋應用程序的代碼。這意味着你不需要為框架所消耗的性能付出成本,並且在應用程序首次加載時沒有額外損失

  你可以使用 Svelte 構建整個應用程序,也可以逐步將其融合到現有的代碼中。你還可以將組件作為獨立的包(package)交付到任何地方,並且不會有傳統框架所帶來的額外開銷。

二、如何看待 svelte 這個前端框架

1、尤雨溪大神的觀點

  作者是 Rich Harris,也就是 Ractive, Rollup 和 Buble 的作者,堪稱前端界的輪子哥,現在又帶來新輪子了!

  這個框架的 API 設計是從 Ractive 那邊傳承過來的(自然跟 Vue 也非常像),但這不是重點。Svelte 的核心思想在於『通過靜態編譯減少框架運行時的代碼量』。舉例來說,當前的框架無論是 React Angular 還是 Vue,不管你怎么編譯,使用的時候必然需要『引入』框架本身,也就是所謂的運行時 (runtime)。但是用 Svelte 就不一樣,一個 Svelte 組件編譯了以后,所有需要的運行時代碼都包含在里面了,除了引入這個組件本身,你不需要再額外引入一個所謂的框架運行時

  當然,這不是說 Svelte 沒有運行時,但是出於兩個原因這個代價可以變得很小

(1)Svelte 的編譯風格是將模板編譯為命令式 (imperative) 的原生 DOM 操作。比如這段模板:

<a>{{ msg }}</a>
// 會被編譯成如下代碼:
function renderMainFragment ( root, component, target ) { var a = document.createElement( 'a' ); var text = document.createTextNode( root.msg ); a.appendChild( text ); target.appendChild( a ) return { update: function ( changed, root ) { text.data = root.msg; }, teardown: function ( detach ) { if ( detach ) a.parentNode.removeChild( a ); } }; }

  可以看到,跟基於 Virtual DOM 的框架相比,這樣的輸出不需要 Virtual DOM 的 diff/patch 操作,自然可以省去大量代碼,同時,性能上也和 vanilla JS 相差無幾(僅就這個簡單示例而言),內存占用更是極佳。這個思路其實並不是它首創,之前有一個性能爆表的模板引擎 Monkberry.js 也是這樣實現的,ng2 的模板編譯其實也跟這個很類似(但是中間加了一層渲染抽象層)。

(2)對於特定功能,Svelte 依然有對應的運行時代碼,比如組件邏輯,if/else 切換邏輯,循環邏輯等等... 但它在編譯時,如果一個功能沒用到,對應的代碼就根本不會被編譯到結果里去。這就好像用 Babel 的時候沒有用到的功能的 helper 是不會被引入的,又好像用 lodash 或者 RxJS 的時候只選擇性地引入對應的函數。

  基於這兩個特點,Svelte 應用的最終代碼量可以非常小。比如它的 TodoMVC min+gzip 之后只有 3kb。

  但是,Svelte 也不是沒有它的潛在問題:

(1)雖然在簡單的 demo 里面代碼量確實非常小,但同樣的組件模板,這樣的 imperative 操作生成的代碼量會比 vdom 渲染函數要大,多個組件中會有很多重復的代碼(雖然 gzip 時候可以緩解,但 parse 和 evaluate 是免不了的)。

  項目里的組件越多,代碼量的差異就會逐漸縮小。

  同時,並不是真正的如宣傳的那樣 “沒有 runtime“,而是根據你的代碼按需 import 而已。

  使用的功能越多,Svelte 要包含的運行時代碼也越多,最終在實際生產項目中能有多少尺寸優勢,其實很難說。

(2)Svelte 在大型應用中的性能還有待觀察,尤其是在大量動態內容和嵌套組件的情況下。它的更新策略決定了它也需要類似 React 的 shouldComponentUpdate 的機制來防止過度更新。

  另一方面,其性能優勢比起現在的主流框架並不是質的區別,現在大部分主流框架的性能都可以做到 vanilla js 的 1.2~1.5 倍慢,基於 Virtual DOM 的 Inferno 更是接近原生,證明了 Virtual DOM 這個方向理論上的可能性,所以可以預見以后 web 的性能瓶頸更多是 DOM 本身而不是框架。

(3)Svelte 的編譯策略決定了它跟 Virtual DOM 絕緣(渲染函數由於其動態性,無法像模板那樣可以被可靠地靜態分析),也就享受不到 Virtual DOM 帶來的諸多好處,比如基於 render function 的組件的強大抽象能力,基於 vdom 做測試,服務端/原生渲染親和性等等。

  這一點在我看來比較關鍵。讓我在一點點性能和 Virtual DOM 之間做抉擇的話,我還是會選擇 Virtual DOM。Vue 3 在保留 Virtual DOM 靈活性的前提下基於模版對渲染函數做 AOT 優化,性能已經做到跟 Svelte 很接近。

  最后,我個人覺得 Svelte 比較有優勢的地方,就是用來編譯可獨立分發的 Web Components。傳統框架和 Web Components 結合最大的問題就在於運行時:單獨分發的 WC 里面直接打包框架運行時,等於每個組件都要復制一份框架;不打包的話,又做不到開箱即用。但 Svelte 受這個問題的限制最小(依然存在重復代碼問題,但取決於你用了多少功能),可以說是最適合這個用例的框架。

作者:尤雨溪 - https://www.zhihu.com/question/53150351/answer/133912199
  其他觀點也可以直接看這篇文章上的觀點

三、尤大親自評測 Vue3 和 Svelte(19個組件后Vue更好!)

  原文地址:https://baijiahao.baidu.com/s?id=1705953978338805887&wfr=spider&for=pc

  本研究旨在展示框架如何在 compile-time 編譯時和 runtime spectrum 運行時找到一個平衡點

(1)Vue 在源碼上使用了一定的 compile-time 編譯時 優化,但選擇較重的 compile-time 返回較小的生成代碼。

(2)Svelte選擇最小的運行時,但具有較重生成的代碼的成本。

(3)Svelte 可以進一步改進其代碼生成來降低代碼輸出嗎?Vue可以進一步改善tree-shaking,使基線(運行時框架)變小嗎?另外一點框架可以找到更好的平衡點嗎?對以上所有的問題的答案回答可能是肯定的。

  從這篇文章學到的總體觀點:

1、Svelte 確實有一個閾值會使得它在一定程度后讓體積大小沒有了優勢;

2、但是在一般情況下,特別是在一些 H5 游戲中,如果你想要獲得 React/Vue 數據驅動的方式編寫應用,但是你又不想要引入他們這么大的運行時,確實來說是一個非常不錯的方案。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM