框架比較
若您正在閱讀此頁面,您可能已經使用其他框架來建構應用程式,並想知道 Mithril.js 是否能更有效地協助您解決問題。
為什麼不用 [您愛用的框架]?
實際上,大多數現代框架都很快,非常適合建構複雜的應用程式,並且如果您知道如何有效地使用它們,則能夠維護。現有許多高度複雜的應用程式實例,它們僅使用幾乎所有流行的框架:Udemy 使用 Angular,AirBnB 使用 React,Gitlab 使用 Vue,Guild Wars 2 使用 Mithril.js(是的,在遊戲內部!)。顯然,這些都是生產級別的框架。
一般而言,如果您的團隊已經在另一個框架/函式庫/堆疊上投入了大量資源,那麼堅持使用它更有意義,除非您的團隊一致認為有非常強烈的理由,足以證明重寫的巨大成本是合理的。
但是,如果您要開始新的專案,請考慮嘗試一下 Mithril.js,至少可以看看 Mithril.js 的採用者從不到 10kb(gzip 壓縮後)的程式碼中獲得了多少價值。Mithril.js 被許多知名公司(例如 Vimeo、Nike、Fitbit)使用,並且它也為大型開源平台提供支援(例如 Lichess、Flarum)。
為什麼要使用 Mithril.js?
一句話:因為 Mithril.js 是實用的。這個 10 分鐘指南 是一個很好的例子:這就是學習元件、XHR 和路由所需的時間 - 這幾乎是建構有用的應用程式所需的知識量。
Mithril.js 的重點在於高效地完成有意義的工作。執行檔案上傳?文件會告訴您如何操作。身份驗證?也有記錄。退出動畫?您明白了。沒有額外的函式庫,沒有魔法。
比較
React
React 是一個由 Facebook 維護的視圖庫。
React 和 Mithril.js 之間有許多相似之處。如果您已經學習了 React,那麼您已經了解了使用 Mithril 建構應用程式所需的幾乎所有知識。
- 它們都使用虛擬 DOM、生命週期方法和基於鍵的協調。
- 它們都透過元件組織視圖。
- 它們都使用 JavaScript 作為視圖中的流程控制機制。
React 和 Mithril.js 之間最明顯的區別在於它們的定位。React 是一個視圖庫,因此典型的基於 React 的應用程式依賴於第三方函式庫來進行路由、XHR 和狀態管理。使用面向函式庫的方法允許開發人員自訂其堆疊,以精確地滿足他們的需求。換句話說,基於 React 的架構在專案之間可能差異很大,且這些專案更有可能超過 1MB 的大小限制。
Mithril.js 內建了用於常見需求(例如路由和 XHR)的模組,並且 指南 示範了慣用的用法。對於重視一致性和容易上手的團隊來說,這種方法更可取。
效能
React 和 Mithril.js 都非常重視渲染效能,但採用不同的方式。過去,React 有兩個 DOM 渲染實作(一個使用 DOM API,另一個使用 innerHTML
)。其即將推出的 fiber 架構引入了工作單位的排程和優先順序。React 還有一個複雜的構建系統,可以禁用各種檢查和錯誤訊息以進行生產部署,以及各種特定於瀏覽器的最佳化。此外,還有幾個面向效能的函式庫,它們利用 React 的 shouldComponentUpdate
hook 和不可變資料結構函式庫的快速物件相等性檢查屬性來減少虛擬 DOM 協調時間。一般來說,React 提升效能的方式是設計相對複雜的解決方案。
Mithril.js 遵循少即是多的思想。它有一個實質上更小、經過積極最佳化的程式碼庫。理由是小的程式碼庫更容易審核和最佳化,最終也能減少需要執行的程式碼。
以下是函式庫載入時間的比較,即解析和運行每個框架的 JavaScript 程式碼所需的時間,方法是在第一行呼叫 console.time()
,並在僅由框架程式碼組成的腳本的最後一行呼叫 console.timeEnd()
。為了方便您閱讀,以下是最佳的 20 個結果,其中記錄程式碼手動添加到捆綁腳本中,從檔案系統運行,在普通的 2010 PC 桌面上使用 Chrome:
React | Mithril.js |
---|---|
55.8 ms | 4.5 ms |
函式庫載入時間在不會長時間保持開啟的應用程式(例如行動裝置中的任何內容)中非常重要,並且無法透過快取或其他最佳化技術來改善。
由於這是一個微基準測試,因此鼓勵您自行複製這些測試,因為硬體效能會嚴重影響測試結果。
請注意,像 Webpack 這樣的捆綁器框架可以在計時器呼叫之前移出依賴項以模擬靜態模組解析,因此您應該從編譯的 CDN 檔案中複製程式碼,或從捆綁器函式庫中開啟輸出檔案,並手動將高解析度計時器呼叫 console.time
和 console.timeEnd
新增到捆綁腳本中。避免使用 new Date
和 performance.now
,因為這些機制在統計上不夠準確。
為了方便您閱讀,以下是適用於在網路上使用 CDN 的基準測試版本:React 的基準測試在此,Mithril.js 的基準測試在此。另請注意,由於從磁碟快取中提取資源,此 CDN 驅動的設定會產生一些額外的開銷(每個資源約 2 毫秒)。由於這些原因,此處的數字並不完全準確,但它們應該足以觀察到 Mithril.js 的初始化速度明顯優於 React。
以下是一個稍微更有意義的基準測試:測量建立 10,000 個 div(和 10,000 個文本節點)的腳本執行時間。同樣,這是 React 和 Mithril.js 的基準測試程式碼。它們的最佳結果如下所示:
React | Mithril.js |
---|---|
99.7 ms | 42.8 ms |
這些數字顯示,Mithril.js 不僅初始化速度明顯更快,還能在 React 準備就緒之前,就能處理超過 20,000 個虛擬 DOM 節點。
更新效能
更新效能甚至比首次渲染效能更為重要,因為更新可能會在單頁應用程式運行時發生多次。
一個用於基準測試更新效能的有用工具是由 Ember 團隊開發的工具,名為 DbMonster。它會盡可能快地更新表格,並測量每秒幀數 (FPS) 和 JavaScript 時間(最小值、最大值和平均值)。FPS 計數可能難以評估,因為它還包括瀏覽器重繪時間和 setTimeout
的限制延遲,因此最值得關注的數字是平均渲染時間。您可以比較 React 實作 和 Mithril.js 實作。範例結果如下所示:
React | Mithril.js |
---|---|
12.1 ms | 6.4 ms |
開發效能
另一個需要注意的是,由於 React 在開發模式下新增了額外的檢查和有用的錯誤訊息,因此它在開發中的速度比用於上述基準測試的生產版本慢。為了說明,這是使用 React 開發版本的上述 10,000 個節點基準測試。
隨插即用替代品
有 幾個 專案 聲稱 與 React 具有 API 對等性(有些透過相容性層函式庫),但它們並不完全相容(例如,PropTypes 支援通常被存根化,有時不支援合成事件,並且某些 API 具有不同的語意)。請注意,這些函式庫通常還包括它們自己的功能,這些功能不是官方 React API 的一部分,如果有人決定切換回 React Fiber,這可能會在未來造成問題。
聲稱檔案較小(與 React 相比)是沒錯的,但這些函式庫中的大多數都比 Mithril.js 的渲染模組略大。Preact 是唯一的例外。
請注意積極的效能聲明,因為某些專案使用的基準測試已知過時且有缺陷(因為它們可以被利用 - 並且已被利用)。Boris Kaul(某些基準測試的作者)詳細撰寫了有關如何進行 Web 框架基準測試的文章。另一個需要注意的是,某些基準測試積極使用高級最佳化功能,因此展示了潛在的效能,即在某些注意事項下可能的效能,但實際上不太可能,除非您主動花時間檢查整個程式碼庫,識別最佳化候選者並評估最佳化注意事項帶來的倒退風險。
為了展現 典型 的效能,此比較頁面中的基準測試以一種公平、直接且慣用的方式實作(也就是您撰寫大部分程式碼的方式),不使用任何技巧或進階最佳化,以避免讓任何框架看起來有不實的優勢。如果您認為此處的任何 DbMonster 實作可以編寫得更慣用,則鼓勵您貢獻 PR。
複雜性
與其他框架相比,React 和 Mithril.js 都具有相對較小的 API 介面,這有助於降低學習曲線。但是,雖然慣用的 Mithril.js 可以在不損失可讀性的情況下使用純 ES5 編寫,並且沒有其他依賴項,但慣用的 React 卻嚴重依賴複雜的工具鏈,例如 Babel 和 JSX 外掛程式。這種複雜性也常見於其生態系統中,例如 Redux 中非標準的物件擴展語法、使用不可變資料函式庫的架構,或是熱模組重新載入等附加功能。
雖然複雜的工具鏈也可以與 Mithril.js 和其他框架一起使用,但強烈建議您在使用 Mithril 時遵循 KISS 和 YAGNI 原則。
學習曲線
React 和 Mithril.js 的學習曲線都相對較平緩。React 的學習曲線主要涉及理解元件及其生命週期。Mithril.js 元件的學習曲線幾乎相同。顯然,Mithril.js 中有更多 API 需要學習,因為 Mithril.js 還包括路由和 XHR,但學習曲線與學習 React、React Router 和像 superagent 或 axios 這樣的 XHR 函式庫非常相似。
慣用的 React 需要對 JSX 及其注意事項有一定的工作知識,因此還有一個與 Babel 相關的小學習曲線。
文件
React 文件清晰且寫得很好,包括良好的 API 參考、入門教程以及涵蓋各種高級概念的頁面。不幸的是,由於 React 僅限於作為一個視圖庫,因此其文件沒有探討如何在真實應用程式的上下文中慣用地使用 React。因此,由於有許多流行的狀態管理函式庫,使用 React 的架構在不同公司(甚至不同專案)之間可能差異很大。
Mithril.js 文件還包括入門、教程、關於高級概念的頁面以及廣泛的 API 參考部分,其中包括輸入/輸出類型資訊、各種常見用例的範例以及關於濫用和反模式的建議。它還包括一個快速參考的速查表。
Mithril.js 文件還示範了簡單、接近底層的解決方案,用於真實應用程式中的常見用例,在這些用例中,適當地告知開發人員 Web 標準現在可能與更大的已建立函式庫相當。
Angular
Angular 是一個由 Google 維護的網頁應用程式框架。
Angular 和 Mithril.js 之間有很大的不同,但它們也有一些相似之處。
- 兩者都支援元件化。
- 兩者都有一系列用於網頁應用程式各個方面的工具(例如路由、XHR)。
Angular 和 Mithril.js 之間最明顯的區別在於它們的複雜性。這可以最容易地在視圖的實作方式中看出。Mithril.js 的視圖是純 JavaScript,並且流程控制是使用 JavaScript 內建機制(例如三元運算符或 Array.prototype.map
)完成的。Angular 實作了一個指令系統來擴展 HTML 視圖,以便可以在 HTML 屬性和插值中評估類似 JavaScript 的表達式。Angular 實際上內建了一個用 JavaScript 編寫的解析器和編譯器來達成這個目的。如果這看起來還不夠複雜,那麼實際上還有兩種編譯模式(一種預設模式,用於動態產生 JavaScript 函數以提高效能,以及 一種較慢的模式 用於處理內容安全策略限制)。
效能
多年來,Angular 在效能方面取得了很大進展。Angular 1 使用了一種稱為髒檢查(dirty checking)的機制,由於需要不斷比較大型 $scope
結構,因此往往會變慢。Angular 2 使用了一種模板變更檢測機制,該機制的效能更高。但是,即使 Angular 進行了改進,Mithril.js 通常也比 Angular 快,因為 Mithril.js 的小程式碼庫更容易檢閱。
由於幾個原因,很難比較 Angular 和 Mithril.js 之間的載入時間。首先,Angular 1 和 2 實際上是完全不同的程式碼庫,並且兩個版本都受到官方支援和維護(目前在野外的大多數 Angular 程式碼庫仍然使用版本 1)。第二個原因是 Angular 和 Mithril.js 都是模組化的。在這兩種情況下,都可以刪除給定應用程式中未使用的框架的很大一部分。
儘管如此,已知最小的 Angular 2 捆綁包是 29kb 的 hello world,使用 Brotli 演算法壓縮(使用標準 gzip 為 35kb),並且刪除了 Angular 的大多數有用功能。相比之下,Mithril.js hello world(包括整個 Mithril.js 核心,帶有完整功能)的 gzip 壓縮後約為 10kb。
此外,請記住,像 Angular 和 Mithril.js 這樣的框架是為非平凡的應用程式設計的,因此設法使用 Angular 的所有 API 介面的應用程式需要下載數百 kb 的框架程式碼,而不僅僅是 29kb。
更新效能
一個用於基準測試更新效能的有用工具是由 Ember 團隊開發的工具,名為 DbMonster。它會盡可能快地更新表格,並測量每秒幀數 (FPS) 和 JavaScript 時間(最小值、最大值和平均值)。FPS 計數可能難以評估,因為它還包括瀏覽器重繪時間和 setTimeout
限制延遲,因此最值得關注的數字是平均渲染時間。您可以比較 Angular 實作 和 Mithril.js 實作。範例結果如下所示:
Angular | Mithril.js |
---|---|
11.5 ms | 6.4 ms |
複雜性
Angular 在它提供的工具數量(以各種指令和服務的形式)方面優於 Mithril.js,但它也複雜得多。比較 Angular 的 API 介面 與 Mithril.js 的 API 介面。您可以自行判斷哪個 API 更容易理解,並且更符合您的需求。
Angular 2 有很多概念需要理解:在語言層面,Typescript 是推薦的語言,除此之外,還有 Angular 特定的模板語法,例如綁定、管道、「安全導航運算符」。您還需要了解架構概念,例如模組、元件、服務、指令等,以及在何處適當地使用什麼。
學習曲線
如果我們比較蘋果對蘋果,Angular 2 和 Mithril.js 具有相似的學習曲線:在這兩者中,元件都是架構的核心方面,並且兩者都具有合理的路由和 XHR 工具。
儘管如此,Angular 有很多概念需要學習,這比 Mithril 更多。它為許多通常可以輕鬆實作的事情提供 Angular 特定的 API(例如,複數化本質上是一個 switch 語句,「required」驗證只是一個相等性檢查等)。Angular 模板還有幾個抽象層,用於模擬 JavaScript 在 Mithril.js 中原生執行的操作。例如,Angular 的 ng-if
/ngIf
是一個 指令,它使用自訂的 解析器 和 編譯器 來評估表達式字串,並模擬詞法範疇。Mithril.js 往往更透明,因此更容易理解。
文件
Angular 2 文件提供了一個廣泛的入門教程,以及另一個實作應用程式的教程。它還有各種高級概念指南、速查表和樣式指南。不幸的是,目前 API 參考還有很多不足之處。一些 API 要么沒有記錄,要么沒有提供 API 可能用於的上下文。
Mithril.js 文件包括入門教程、關於高級概念的頁面以及廣泛的 API 參考部分,其中包括輸入/輸出類型資訊、各種常見用例的範例以及關於濫用和反模式的建議。它還包括一個快速參考的速查表。
Mithril.js 文件還示範了簡單、接近底層的解決方案,用於真實應用程式中的常見用例,在這些用例中,適當地告知開發人員 Web 標準現在可能與更大的已建立函式庫相當。
Vue
Vue 是一個類似於 Angular 的視圖庫。
Vue 和 Mithril.js 之間有很多不同之處,但它們也有一些相似之處。
- 它們都使用虛擬 DOM 和生命週期方法。
- 兩者都透過元件組織視圖。
Vue 2 使用 Snabbdom 的一個分支作為其虛擬 DOM 系統。此外,Vue 還提供用於路由和狀態管理的工具作為單獨的模組。Vue 看起來與 Angular 非常相似,並提供類似的指令系統、基於 HTML 的模板和邏輯流程指令。它與 Angular 的不同之處在於它實作了一個猴子補丁(monkeypatching)反應式系統,該系統會覆蓋元件資料樹中的本機方法(而 Angular 1 使用髒檢查(dirty checking)和摘要/應用週期來實現類似的結果)。與 Angular 2 類似,Vue 將 HTML 模板編譯為函數,但編譯後的函數看起來更像 Mithril.js 或 React 的視圖,而不是 Angular 的編譯渲染函數。
在比較蘋果對蘋果時,Vue 比 Angular 小得多,但不如 Mithril.js 小(Vue 核心約為 23kb gzip 壓縮,而 Mithril.js 中等效的渲染模組約為 4kb gzip 壓縮)。兩者都具有相似的效能特性,但基準測試通常表明 Mithril.js 略快。
效能
以下是函式庫載入時間的比較,即解析和運行每個框架的 JavaScript 程式碼所需的時間,方法是在第一行呼叫 console.time()
,並在僅由框架程式碼組成的腳本的最後一行呼叫 console.timeEnd()
。為了方便您閱讀,以下是最佳的 20 個結果,其中記錄程式碼手動添加到捆綁腳本中,從檔案系統運行,在普通的 2010 PC 桌面上使用 Chrome:
Vue | Mithril.js |
---|---|
21.8 ms | 4.5 ms |
函式庫載入時間在不會長時間保持開啟的應用程式(例如行動裝置中的任何內容)中非常重要,並且無法透過快取或其他最佳化技術來改善。
更新效能
Ember 團隊開發了一個名為 DbMonster 的工具,可用於評估更新效能。它會盡可能快地更新表格,並測量每秒幀數 (FPS) 和 JavaScript 時間(最小值、最大值和平均值)。由於 FPS 計數也包括瀏覽器重繪時間和 setTimeout
鉗制延遲,因此很難評估,因此最有意義的數字是平均渲染時間。您可以比較 Vue 實作 和 Mithril.js 實作。這兩個實作都很簡單(即沒有最佳化)。範例結果如下所示:
Vue | Mithril.js |
---|---|
9.8 ms | 6.4 ms |
複雜性
Vue 受到 Angular 的很大啟發,具有許多 Angular 的特性,例如指令、篩選器、雙向綁定和 v-cloak
。同時,它也具有受到 React 啟發的特性,例如元件。從 Vue 2.0 開始,也可以使用 hyperscript/JSX 語法編寫模板(除了單檔案元件和各種基於 webpack 的語言轉換外掛程式之外)。Vue 提供雙向資料綁定和一個可選的類似 Redux 的狀態管理函式庫,但與 Angular 不同,它不提供樣式指南。多種做事方式可能會導致長期專案中的架構碎片化。
Mithril.js 的概念要少得多,並且通常根據元件和資料層來組織應用程式。Mithril.js 中的所有元件建立樣式都僅使用本機 JavaScript 功能輸出相同的 vnode 結構。依賴於語言的直接後果是更少的工具和更簡單的專案設定。
文件
Vue 和 Mithril.js 都有良好的文件。兩者都包括一個帶有範例的良好 API 參考、入門教程以及涵蓋各種高級概念的頁面。
但是,由於 Vue 的多種做事方式,某些事情可能沒有得到充分記錄。例如,它們的 hyperscript 被大量掩蓋。
如果一個主題涉及 Mithril 範圍之外的事情,Mithril.js 文件通常會提供非常詳盡的說明。例如,當一個主題涉及第三方函式庫時,Mithril.js 文件會逐步介紹第三方函式庫的安裝過程。Mithril.js 文件還經常示範簡單、接近底層的解決方案,用於真實應用程式中的常見用例,在這些用例中,適當地告知開發人員 Web 標準現在可能與更大的已建立函式庫相當。
Mithril.js 的教程也比 Vue 的教程涵蓋了更多的內容:Vue 教程 在完成了幾頁以涵蓋其大型核心 API 後,以一個簡單的本地待辦事項清單結束。Mithril.js 的 10 分鐘指南 涵蓋了其大部分 API,甚至涵蓋了真實應用程式的關鍵方面,例如從伺服器提取資料和路由。如果這還不夠,還有一個 更長、更徹底的教程。