2020年Github星級前20名JavaScript框架性能比較

最近在瀏覽網頁的時候意識到前端這兩年沒有出現一個好的JavaScript框架了。在這個不平凡的2020年結束之前,來看看2020年流行腳本庫之間的性能對比。
什么Javascript框架最流行呢? 在這里就以Github上星級數排名20的JavaScript框架進行對比,用JS Framework Benchmark對它們進行比較。
聲明:此比較在整個過程中很有趣,也可能具有教育意義。和往常一樣,這里的每個庫對于大多數事情來說都足夠高效。如果有什么要強調的是,性能可以來自多種不同的技術。雖然可以將其用作參考,但應該獨立驗證各個用例的性能。可以在這里找到最新的官方結果。在此聲明,比較只是客觀,實際開發過程需要結合團隊水平、協作情況、效率等綜合考慮。
對比
采用最新的谷歌瀏覽器Chrome 87關鍵結果的JS Framework Benchmark。它們在Fedora 33下的Core i7 Razor Blade 15上運行,且關閉緩解。
過濾掉了所有有問題的實現,然后獲得了Github星級數量前20的腳本庫。對于具有多個版本的庫,沒有使用第三方庫獲取它們的最新版本和性能最高的變體。下面是Github星級排名前20的腳本庫的信息及星級情況。
- Vue (177k)
- React (161k)
- Angular (68.9k)
- Svelte (40.5k)
- Preact (27.9k)
- Ember (21.7k)
- HyperApp(18.2k)
- Inferno (14.6k)
- Riot (14.4k)
- Yew (14.2k)
- Mithril (12.5k)
- Alpine (12.4k)
- Knockout (9.9k)
- Marko (9.9k)
- lit-html (6.9k)
- Rax (7k)
- Elm (6.2k)
- Ractive (5.8k)
- Solid (4.7k)
- Imba (4.1k)
注意:我將把
LitElement實現用作lit-html示例,因為標準示例已被標記為問題。開銷應該最小,因為它是包裝在單個Web組件中的原始lit-html。
這是當前Web開發生態系統中相當不錯的一部分。盡管Github Stars并不是全部,但比較中有100多個庫,因此需要選擇相對比較流行的。
每個庫將在3個類別中進行比較:
- DOM性能
- 啟動指標
- 內存使用情況
此外,將框架分為4組,以將它們與原始性能同級進行最佳比較。但是,將在所有三個方面對腳本庫進行排名。
在每個組中,將存在參考Vanilla JavaScript條目。使用所有最佳技術,此實現都經過了最優化,以達到最佳性能。它將作為所有比較的基準。
第4組-標準性能
這是最大的組,由一些最受歡迎的腳本庫組成。還有許多來自Facebook、Google、eBay和阿里巴巴等公司支持的公司。這些腳本庫要么在某個方面不太注重性能,要么突出某個領域的性能,而在其他方面表現不佳。

這里有很多紅色和橙色,但請記住,這些庫平均僅比我們在此處使用的痛苦手工制作的命令式Vanilla JavaScript示例慢大約2倍。 400ms與200ms有何不同?
在原始性能方面,React是該組的領導者。考慮到架構的差異性,盡管它從未間斷,但React、Marko、Angular和Ember的整體差距不大。仍然是React,這是React Hooks的實現,在這里是領導者。對于所有指向額外的函數創建并堅持使用類的人來說,性能參數不在您身邊。React Hooks是使用React的最高效的方法。
這里的大多數庫要么幼稚的列表排序導致交換行性能確實很差,要么創建成本很高。Ember是這種情況的極端案例,因為它的更新性能比該組中的其他成員要好得多,但在某些最壞的情況下卻是創建過程。
最慢的庫(Knockout,Ractive和Alpine)都是具有類似架構的細粒度反應庫。Knockout和Ractive(也由Svelte的作者Rich Harris撰寫)來自2010年初VDOM庫主導之前。我還懷疑Alpine是否期望使用其JavaScript方法來渲染1萬行。在比較之后,我們將看不到另一個純細粒度的反應式庫。
接下來,我們將主要基于庫包的大小來比較類別的啟動指標。

此處清單變化很大。在Alpine表現最差的地方,我們可以看到它擁有最小的bundle大小和最快的啟動時間。Marko(來自eBay)緊隨其后,其次是Rax(來自阿里巴巴)。所有這三個庫都是為服務器端渲染而構建的,主要是通過更輕松的客戶端交互來實現的。這就是為什么他們在性能方面處于第4組,卻在這里領先于啟動的原因。
表格的后半部分是我們在基準測試中擁有的最大的包軟件,以Ember結尾,是任何其他實現的兩倍以上。我不知道為什么要花費超過半兆字節才能呈現此表。但這確實會損害啟動性能。
我們要看的最后一類是內存消耗。

內存傾向于反映我們已經看到的模式,因為它對性能有很大的影響,而較大的庫則傾向于使用更多的內存。Alpine,Marko和React引領潮流。老化的細粒度反應庫使用最多的Ember。Ember是巨大的。僅在頁面上渲染6個按鈕之后,它已經使用了比Vanilla在整個套件中使用的更多的內存。
第4組結果
通常,該組在GitHub上代表30萬顆星,可能是NPM下載量的最大部分,但Marko和Alpine在此人群中的平均排名最高。在性能方面,React排名第三,僅次于他們。
第3組-性能意識
在這些框架中,您可以知道已經考慮了性能。他們意識到規模,并且在創建和更新成本之間找到了平衡。我們看到了各種各樣的方法。Yew中的一個Web Assembly框架(用Rust編寫),LitElement中的一個Web組件。
事不宜遲,讓我們看看它們的工作方式。

分數已經提高了一點,我們看到的差距甚至更大。Preact是該組中性能最高的,僅增加了LitElement。Vue 3和Riot捆綁在一起,這兩個庫都位于中間,它們的歷史都包括反應性和VDOM。Mithril是最早將性能放在首位的VDOM庫之一,Yew是唯一的WASM庫尾部。
在性能方面,所有這些庫都是相似的。在這堆中沒有純的反應庫。它們都使用自頂向下的呈現方式,無論是VDOM還是簡單的Tag Template Literal diff。與上一組相比,它們的對帳清單更智能(請參閱交換行性能)。但是,大多數仍然具有某些最慢的選擇行性能。
Yew是例外,但在其他方面則較慢。讓我們看看其余的測試是否有幫助。

情況有所改觀,但在啟動指標方面,Preact仍然處于領先地位。Yew是這一堆中唯一真正的大型的腳本庫。WASM庫確實傾向于更大的一邊。
再次,我們看到一種結果配對。Vue是僅次于Yew的第二大腳本庫。Preact和Riot非常緊湊。Mithril和LitElement在中間
Preact是React的4kb替代品,絕對是我們迄今為止所看到的最小的庫。但是最小的庫仍在繼續。盡管如此,這個范圍內的任何庫都不應該太關注它們的包大小。

Yew這次贏了。在所有經過測試的框架中,它具有最小的內存占用量。WASM庫在這方面表現也很好。其他都非常接近。Mithril和Preact是最差的,但差距不大。
從這里也沒什么可聊的了。可能會認為LitElement示例可能比其他非yew庫更輕,因為它不像其他庫那樣使用虛擬DOM。但正如我們稍后將看到的,VDOM并不意味著更多的內存。
第3組結果
Riot和Preact平均排名最好,其次是LitElement,排名第三。Riot雖然表現不佳,但在這個小組中沒有任何弱點,最終在比較中勝出。但是,對這些框架中的任何一個都不會感到失望。通過WASM和Web組件,它們代表了許多人認為的Web的未來。
第二組-性能冠軍
這個組的腳本庫是競爭激烈的。我們擁有大多數被稱為編譯語言的庫。每一種都有自己的特色。我們擁有不變的結構化Elm,受Ruby啟發的Imba和“消失的” Svelte。
注意:并不是每個人都熟悉Svelte以前的“消失的框架”綽號。它描述了從輸出中基本進行自我編譯的能力。
奇怪的是HyperApp,它與其他應用程序完全相反。沒有編譯器。沒有模板。只需h個功能和一個最小的Virtual DOM

好吧,最小的虛擬DOM勝出。與最近的言論相反,事實證明虛擬DOM不僅是性能不佳的秘訣,而且編譯并沒有給其他庫帶來幫助。
在已編譯的庫中,我們實際上看到了3種不同的方法來渲染所有具有大約相同的平均性能。
- Imba使用DOM協調(更接近我們之前看到的LitElement)
- Elm使用虛擬DOM
- 最后一個Svelte使用組件反應系統
您應該注意,虛擬DOM庫的選擇行最差,因為這是它們的額外工作所在。但是這些庫還具有更快的初始渲染。如果您仔細觀察到目前為止的結果,您應該注意到與響應式庫相比,虛擬DOM庫之間的共享特性。但除此之外,性能還很嚴格。
因此,讓我們繼續。我們的編譯器如何調整啟動時間/包大小?

好吧,正如您所看到的那樣,這個小的虛擬DOM庫不僅性能更高,而且比其他的更小。實際上,HyperApp是我們所有庫中最小的實現。編譯器無法贏得成功。
它和Svelte都比我們的Vanilla JavaScript參考構建小。那怎么可能?以一種更可重用的方式編寫更少的代碼來編寫抽象。Vanilla JS實現針對性能而非大小進行了優化。
Elm在這一組中仍處于競爭規模。然而,Imba開始進入group 4中的一些庫的范圍。
好了,來對比內存,編譯器大放異彩的最后機會。

內存接近,幾乎是平局,但是Svelte最終為編譯器贏得了勝利。對虛擬DOM的一些甜蜜的報復顯示它比它更小,更快。
老實說,所有這些庫都具有出色的內存配置文件。現在應該很清楚,更少的內存和更好的性能之間的關系。
第2組結果
不要相信炒作?
不。更多的事情比表面上看起來復雜。精心設計的系統,無論是運行時還是編譯時,或者無論采用何種技術方法,都可以制成高性能的系統。
HyperApp是該組的明顯贏家,其后是Svelte,其次是Elm和Imba。通過這種對性能的專注,您知道這些庫在大多數情況下都可以提供,并且始終顯示在基準測試的頂部。
第一組-性能精英
在某種程度上,這可能被稱為“令人眩目的快”,我相信它曾經是這些庫的標語之一。如果你要跟蹤的話,現在只剩下2個腳本庫了。事實上,這個類別中有少數腳本庫在不斷地挑戰邊界。但流行的只有2種。它們比手工優化的原始Vanilla JS平均慢不到20%。

這是值得一看的。這里我們有兩個庫,如果看它們的代碼,它們可能被認為是兄弟,但使用的方法完全不同。Inferno是世界上性能最好的虛擬DOM庫之一。沒錯,前5名中有3個是虛擬DOM庫。select row測試的放緩可以看作是證據。
另一方面,Solid使用細粒度的反應性,例如第4組中最慢的舊庫。重新出現此技術的位置很奇怪,但正如我們所見,Solid解決了它們的弱點。創建時間與更新時間一樣快。與Vanilla JavaScript的5%差距令人難以置信。
奇怪的是,Inferno和Solid的共同點是JSX模板和React受啟發的API。對于所有其他具有優化的自定義DSL的庫,也許您不會期望在性能的頂峰找到任何東西。但是,正如HyperApp所示,某些事情對性能的影響比人們想象的要小。

Solid將HyperApp和Svelte作為第三個庫加入,其庫比Vanilla JS實現小。但是Inferno也不是懈怠。
似乎性能庫較小時,有時添加更多代碼可以提高性能。更好的列表協調算法,更明確的防護措施,更精細的更新。
Inferno可能比前幾組中的某些庫更大,但它仍然是一個10kb以下的庫,在性能上幾乎勝過所有。

在那里。除了Yew及其對WASM的使用以外,它們是整個競爭中最低的內存消耗框架。考慮到他們的表現,這并不奇怪。
這種內存消耗數字反映了對對象的非常仔細的考慮,并創建了閉包。其中很多確實來自兩個庫都進行的定制JSX轉換。
內存性能的提高對Solid尤為重要,因為Solid與大多數細粒度的反應式庫一樣,都將CPU開銷換成了內存消耗。在這種比較中,能夠征服內存開銷是Solid如何采用與大多數最慢的庫類似的技術并使之成為最快的方法的很大一部分。
第一組結果
天空是極限。
…或者說Vanilla JavaScript是。但是我們這里的聲明性庫性能如此之差,您永遠都不會知道它們之間的區別。當使用DOM時,我們要認真考慮要面對的問題,許多不同的技術可以有效地渲染DOM。
我們在這里看到它。Solid憑借十年前被認為是古老而緩慢的技術而獲得了性能冠軍,而Inferno再次證明了Virtual DOM不能有效地完成任何工作。
結論
在構建JavaScript前端時,我們有很多選擇。這只是快速了解框架帶來的性能開銷。當涉及到應用程序中的實際性能時,用戶代碼具有更大的影響。
但是,我真正想在這里打動的是,測試您的解決方案并了解性能是很重要的。現實總是與營銷不同。虛擬DOM不能保證很慢。不能保證編譯器會產生最小的包。自定義模板DSL不能保證是最佳的。
最后,我將為您提供完整的表,將所有庫一起顯示。僅僅因為圖書館快要結束了,并不一定意味著它很慢,但是與這些競爭激烈的競爭對手相比,它的得分更差。
所有框架
單個圖表中的所有框架。
性能

啟動

內存

最終排名
所有結果都添加到一個列表中(第1名獲得20分,最后1名獲得分)。在平局的情況下,成績優先。
- Solid (57)
- HyperApp (54)
- Inferno (51)
- Svelte (51)
- Elm (46)
- Riot (40)
- Preact (39)
- Imba (36)
- lit-html (36)
- Yew (32)
- Vue (29)
- Mithril (29)
- Marko (28)
- Alpine (28)
- React (19)
- Rax (16)
- Angular (12)
- Knockout (11)
- Ractive (8)
- Ember (6)