JavaScript框架對比及案例(React、Vue 及 Hyperapp)
在我的上一篇文章中,我試圖解釋為什么我認(rèn)為 Hyperapp 是一個 React 或 Vue 的可用替代品,原因是,我發(fā)現(xiàn)它易于起步。許多人批評這篇文章,認(rèn)為它自以為是,并沒有給其它框架一個展示自己的機(jī)會。因此,在這篇文章中,我將盡可能客觀的通過提供一些最小化的例子來比較這三個框架,以展示它們的能力。
耳熟能詳?shù)挠嫊r器例子
計時器可能是響應(yīng)式編程中最常用的例子之一,極其易于理解:
- 你需要一個變量
count
保持對計數(shù)器的追蹤。 - 你需要兩個方法來增加或減少
count
變量的值。 - 你需要一種方法來渲染
count
變量,并將其呈現(xiàn)給用戶。 - 你需要掛載到這兩個方法上的兩個按鈕,以便在用戶和它們產(chǎn)生交互時變更
count
變量。
下述代碼是上述所有三個框架的實現(xiàn):
使用 React、Vue 和 Hyperapp 實現(xiàn)的計數(shù)器
這里或許會有很多要做的事情,特別是當(dāng)你并不熟悉其中的一個或多個步驟的時候,因此,我們來一步一步解構(gòu)這些代碼:
- 這三個框架的頂部都有一些
import
語句 - React 更推崇面向?qū)ο蟮姆妒剑褪莿?chuàng)建一個
Counter
組件的class
。Vue 遵循類似的范式,通過創(chuàng)建一個新的Vue
類的實例并將信息傳遞給它來實現(xiàn)。最后,Hyperapp 堅持函數(shù)范式,同時完全彼此分離view
、state
和action
。 - 就
count
變量而言, React 在組件的構(gòu)造函數(shù)內(nèi)對其進(jìn)行實例化,而 Vue 和 Hyperapp 則分別是在它們的data
和state
中設(shè)置這些屬性。 - 繼續(xù)看,你可能注意到 React 和 Vue 有相同的方法來與
count
變量進(jìn)行交互。 React 使用繼承自React.Component
的setState
方法來修改它的狀態(tài),而 Vue 直接修改this.count
。 Hyperapp 使用 ES6 的雙箭頭語法來實現(xiàn)這個方法,而據(jù)我所知,這是唯一一個推薦使用這種語法的框架,React 和 Vue 需要在它們的方法內(nèi)使用this
。另一方面,Hyperapp 的方法需要將狀態(tài)作為參數(shù),這意味著可以在不同的上下文中重用它們。 - 這三個框架的渲染部分實際上是相同的。唯一的細(xì)微差別是 Vue 需要一個函數(shù)
h
作為參數(shù)傳遞給渲染器,事實上 Hyperapp 使用onclick
替代onClick
,以及基于每個框架中實現(xiàn)狀態(tài)的方式引用count
變量。 - 最后,所有的三個框架都被掛載到了
#app
元素上。每個框架都有稍微不同的語法,Vue 則使用了最直接的語法,通過使用元素選擇器而不是使用元素來提供最大的通用性。
計數(shù)器案例對比意見
同時比較所有的三個框架,Hyperapp 需要最少的代碼來實現(xiàn)計數(shù)器,并且它是唯一一個使用函數(shù)范式的框架。然而,Vue 的代碼在絕對長度上似乎更短一些,元素選擇器的掛載方式是一個很好的增強(qiáng)。React 的代碼看起來最多,但是并不意味著代碼不好理解。
使用異步代碼
偶爾你可能需要處理異步代碼。最常見的異步操作之一是發(fā)送請求給一個 API。為了這個例子的目的,我將使用一個[占位 API] 以及一些假數(shù)據(jù)來渲染一個文章列表。必須做的事情如下:
- 在狀態(tài)里保存一個
posts
的數(shù)組 - 使用一個方法和正確的 URL 來調(diào)用
fetch()
,等待返回數(shù)據(jù),轉(zhuǎn)化為 JSON,并最終使用接收到的數(shù)據(jù)更新posts
變量。 - 渲染一個按鈕,這個按鈕將調(diào)用抓取文章的方法。
- 渲染有主鍵的
posts
列表。
從一個 RESTFul API 抓取數(shù)據(jù)
讓我們分解上面的代碼,并比較三個框架:
- 與上面的技術(shù)里例子類似,這三個框架之間的存儲狀態(tài)、渲染視圖和掛載非常相似。這些差異與上面的討論相同。
- 在三個框架中使用
fetch()
抓取數(shù)據(jù)都非常簡單,并且可以像預(yù)期一樣工作。然而其中的關(guān)鍵在于, Hyperapp 處理異步操作和其它兩種框架有些不同。當(dāng)數(shù)據(jù)被接收到并轉(zhuǎn)換為 JSON 時,該操作將調(diào)用不同的同步動作以取代直接在異步操作中修改狀態(tài)。 - 就代碼長度而言,Hyperapp 依然只用最少的代碼行數(shù)實現(xiàn)了相同的結(jié)果,但是 Vue 的代碼看起來不那么的冗長,同時擁有最少的絕對字符長度。
異步代碼對比意見
無論你選擇哪種框架,異步操作都非常簡單。在應(yīng)用異步操作時, Hyperapp 可能會迫使你去遵循編寫更加函數(shù)化和模塊化的代碼的方式。但是另外兩個框架也確實可以做到這一點(diǎn),并且在這一方面給你提供更多的選擇。
To-Do 列表組件案例
在響應(yīng)式編程中,最出名的例子可能是使用每一個框架里來實現(xiàn) To-Do 列表。我不打算在這里實現(xiàn)整個部分,我只實現(xiàn)一個無狀態(tài)的組件,來展示三個框架如何創(chuàng)建更小的可復(fù)用的塊來協(xié)助構(gòu)建應(yīng)用程序。
示例 TodoItem 實現(xiàn)
上面的圖片展示了每一個框架一個例子,并為 React 提供了一個額外的例子。接下來是我們從它們四個中看到的:
- React 在編程范式上最為靈活。它支持函數(shù)組件,也支持類組件。它還支持你在右下角看到的 Hyperapp 組件,無需任何修改。
- Hyperapp 還支持 React 的函數(shù)組件實現(xiàn),這意味著兩個框架之間還有很多的實驗空間。
- 最后出現(xiàn)的 Vue 有著其合理而又奇怪的語法,即使是對另外兩個框架很有經(jīng)驗的人,也不能馬上理解其含義。
- 在長度方面,所有的案例代碼長度非常相似,在 React 的一些方法中稍微冗長一些。
To-Do 列表項目對比意見
Vue 需要花費(fèi)一些時間來熟悉,因為它的模板和其它兩個框架有一些不同。React 非常的靈活,支持多種不同的方法來創(chuàng)建組件,而 HyperApp 保持一切簡單,并提供與 React 的兼容性,以免你希望在某些時刻進(jìn)行切換。
生命周期方法比較
另一個關(guān)鍵對比是組件的生命周期事件,每一個框架允許你根據(jù)你的需要來訂閱和處理事件。下面是我根據(jù)各框架的 API 參考手冊創(chuàng)建的表格:
生命周期方式比較
- Vue 提供了最多的生命周期鉤子,提供了處理生命周期事件之前或之后發(fā)生的任何事件的機(jī)會。這能有效幫助管理復(fù)雜的組件。
- React 和 Hyperapp 的生命周期鉤子非常類似,React 將
unmount
和destory
綁定在了一起,而 Hyperapp 則將create
和mount
綁定在了一起。兩者在處理生命周期事件方面都提供了相當(dāng)多的控制。 - Vue 根本沒有處理
unmount
(據(jù)我所理解),而是依賴于destroy
事件在組件稍后的生命周期進(jìn)行處理。 React 不處理destory
事件,而是選擇只處理unmount
事件。最終,HyperApp 不處理create
事件,取而代之的是只依賴mount
事件。
生命周期對比意見
總的來說,每個框架都提供了生命周期組件,它們幫助你處理組件生命周期中的許多事情。這三個框架都為它們的生命周期提供了鉤子,其之間的細(xì)微差別,可能源自于實現(xiàn)和方案上的根本差異。通過提供更細(xì)粒度的時間處理,Vue 可以更進(jìn)一步的允許你在開始或結(jié)束之后處理生命周期事件。
性能比較
除了易用性和編碼技術(shù)以外,性能也是大多數(shù)開發(fā)人員考慮的關(guān)鍵因素,尤其是在進(jìn)行更復(fù)雜的應(yīng)用程序時。js-framework-benchmark 是一個很好的用于比較框架的工具,所以讓我們看看每一組測評數(shù)據(jù)數(shù)組都說了些什么:
測評操作表
- 與三個框架的有主鍵操作相比,無主鍵操作更快。
- 無主鍵的 React 在所有六種對比中擁有最強(qiáng)的性能,它在所有測試上都有令人深刻的表現(xiàn)。
- 有主鍵的 Vue 只比有主鍵的 React 性能稍強(qiáng),而無主鍵的 Vue 要比無主鍵的 React 性能明顯差。
- Vue 和 Hyperapp 在進(jìn)行局部更新的性能測試時遇見了一些問題,與此同時,React 似乎對該問題進(jìn)行很好的優(yōu)化。
啟動測試
- Hyperapp 是三個框架中最輕量的,而 React 和 Vue 有非常小的大小差異。
- Hyperapp 具有最快的啟動時間,這得益于它極小的大小和極簡的 API
- Vue 在啟動上比 React 好一些,但是差異非常小。
內(nèi)存分配測試
- Hyperapp 是三者中對資源依賴最小的一個,與其它兩者相比,任何一個操作都需要更少的內(nèi)存。
- 資源消耗不是非常高,三者都應(yīng)該在現(xiàn)代硬件上進(jìn)行類似的操作。
性能對比意見
如果性能是一個問題,你應(yīng)該考慮你正在使用什么樣的應(yīng)用程序以及你的需求是什么??雌饋?Vue 和 React 用于更復(fù)雜的應(yīng)用程序更好,而 Hyperapp 更適合于更小的應(yīng)用程序、更少的數(shù)據(jù)處理和需要快速啟動的應(yīng)用程序,以及需要在低端硬件上工作的應(yīng)用程序。
但是,要記住,這些測試遠(yuǎn)不能代表一般場景,所以在現(xiàn)實場景中可能會看到不同的結(jié)果。
額外備注
比較 React、Vue 和 Hyperapp 可能像在許多方面比較蘋果、橘子。關(guān)于這些框架還有一些其它的考慮,它們可以幫助你決定使用另一個框架。
- React 通過引入片段,避免了相鄰的 JSX 元素必須封裝在父元素中的問題,這些元素允許你將子元素列表分組,而無需向 DOM 添加額外的節(jié)點(diǎn)。
- React 還為你提供更高級別的組件,而 VUE 為你提供重用組件功能的 MIXIN。
- Vue 允許使用模板來分離結(jié)構(gòu)和功能,從而更好的分離關(guān)注點(diǎn)。
- 與其它兩個相比,Hyperapp 感覺像是一個較低級別的 API,它的代碼短得多,如果你愿意調(diào)整它并學(xué)習(xí)它的工作原理,那么它可以提供更多的通用性。
結(jié)論
我認(rèn)為如果你已經(jīng)閱讀了這么多,你已經(jīng)知道哪種工具更適合你的需求。畢竟,這不是討論哪一個更好,而是討論哪一個更適合每種情況??偠灾?
- React 是一個非常強(qiáng)大的工具,圍繞它有大規(guī)模的開發(fā)者社區(qū),可能會幫助你找到一個工作。入門并不難,但是掌握它肯定需要很多時間。然而,這是非常值得去花費(fèi)你的時間全面掌握的。
- 如果你過去曾使用過另外的 JavaScript 框架,Vue 可能看起來有點(diǎn)奇怪,但它也是一個非常有趣的工具。如果 React 不是你所喜歡的,那么它可能是一個可行的、值得學(xué)習(xí)的選擇。它有一些非??岬膬?nèi)置功能,其社區(qū)也在增長中,甚至可能要比 React 增長還要快。
- 最后,Hyperapp 是一個為小型項目而生的很酷的小框架,也是初學(xué)者入門的好地方。它提供比 React 或 Vue 更少的工具,但是它能幫助你快速構(gòu)建原型并理解許多基本原理。你為它編寫的許多代碼和其它兩個框架兼容,要么立即能用,或者是稍做更改就行,你可以在對它們中另外一個有信心時切換框架。