對比其他框架
React
React 和 Vue 有許多相似之處,它們都有:
- 使用 Virtual DOM
- 提供了響應式(Reactive)和組件化(Composable)的視圖組件。
- 將注意力集中保持在核心庫,伴隨於此,有配套的路由和負責處理全局狀態管理的庫。
性能簡介
Vue 的性能是優於 React 的。如果你對此表示懷疑,請繼續閱讀。我們會解釋為什么會這樣(並且會提供一個與 React 團隊共同約定的比較基准)。
渲染性能
在渲染用戶界面時,DOM 操作成本是最高的,不幸的是沒有庫可以讓這些原始操作變得更快。
我們能做到的最好效果就是:
- 盡量減少 DOM 操作。Vue 和 React 都使用虛擬 DOM 來實現,並且兩者工作的效果一樣好。
- 盡量減少除 DOM 操作以外的其他操作。這是 Vue 和 React 所不同的地方。
在 React 中,我們設定渲染一個元素的額外開銷是 1,而平均渲染一個組件的開銷是 2。那么在 Vue 中,一個元素的開銷更像是 0.1,但是平均組件的開銷將會是 4,這是由於我們需要設定響應系統所導致的。
這意味着:在典型的應用中,由於需要渲染的元素比組件的數量是更多的,因此 Vue 的性能表現將會遠優於 React。然而,在極端情況下,比如每個組件只渲染一個元素,Vue 就會通常更慢一些。當然接下來還有其他的原因。
Vue 和 React 也提供功能性組件,這些組件因為都是沒有聲明,沒有實例化的,因此會花費更少的開銷。當這些都用於關鍵性能的場景時,Vue 將會更快。為了證明這點,我們建立了一個簡單的參照項目,它負責渲染 10,000 個列表項 100 次。我們鼓勵你基於此去嘗試運行一下。然而在實際上,由於瀏覽器和硬件的差異甚至 JavaScript 引擎的不同,結果都會相應有所不同。
如果你懶得去做,下面的數值是來自於一個 2014 年產的 MacBook Air 並在 Chrome 52 版本下運行所產生的。為了避免偶然性,每個參照項目都分別運行 20 次並取自最好的結果:
Vue | React | |
---|---|---|
Fastest | 23ms | 63ms |
Median | 42ms | 81ms |
Average | 51ms | 94ms |
95th Perc. | 73ms | 164ms |
Slowest | 343ms | 453ms |
更新性能
在 React 中,你需要在處處去實現 shouldComponentUpdate
,並且用不可變數據結構才能實現最優化的渲染。在 Vue 中,組件的依賴被自動追蹤,所以當這些依賴項變動時,它才會更新。唯一需要注意的可能需要進一步優化的一點是在長列表中,需要在每項上添加一個 key
屬性。
這意味着,未經優化的 Vue 相比未經優化的 React 要快的多。由於 Vue 改進過渲染性能,甚至全面優化過的 React 通常也會慢於開箱即用的 Vue。
開發中
顯然,在生產環境中的性能是至關重要的,目前為止我們所具體討論的便是針對此環境。但開發過程中的表現也不容小視。不錯的是用 Vue 和 React 開發大多數應用的速度都是足夠快的。
然而,假如你要開發一個對性能要求比較高的數據可視化或者動畫的應用時,你需要了解到下面這點:在開發中,Vue 每秒最高處理 10 幀,而 React 每秒最高處理不到 1 幀。
這是由於 React 有大量的檢查機制,這會讓它提供許多有用的警告和錯誤提示信息。我們同樣認為這些是很重要的,但是我們在實現這些檢查時,也更加密切地關注了性能方面。
HTML & CSS
在 React 中,它們都是 JavaScript 編寫的,聽起來這十分簡單和優雅。然而不幸的事實是,JavaScript 內的 HTML 和 CSS 會產生很多痛點。在 Vue 中我們采用 Web 技術並在其上進行擴展。接下來將通過一些實例向你展示這意味的是什么。
JSX vs Templates
在 React 中,所有的組件的渲染功能都依靠 JSX。JSX 是使用 XML 語法編寫 Javascript 的一種語法糖。這有一個通過React社區審核過的例子:
render () {
let { items } = this.props
let children
if ( items.length > 0 ) {
children = (
<ul>
{items.map( item =>
<li key={item.id}>{item.name}</li>
)}
</ul>
)
} else {
children = <p>No items found.</p>
}
return (
<div className = 'list-container'>
{children}
</div>
)
}
|
JSX 的渲染功能有下面這些優勢:
- 你可以使用完整的編程語言 JavaScript 功能來構建你的視圖頁面。
- 工具對 JSX 的支持相比於現有可用的其他 Vue 模板還是比較先進的(比如,linting、類型檢查、編輯器的自動完成)。
在 Vue 中,由於有時需要用這些功能,我們也提供了渲染功能 並且支持了 JSX。然而,對於大多數組件來說,渲染功能是不推薦使用了。
在這方面,我們提供的是更簡單的模板:
<template>
<div class="list-container">
<ul v-if="items.length">
<li v-for="item in items">
{{ item.name }}
</li>
</ul>
<p v-else>No items found.</p>
</div>
</template>
|
優點如下:
- 在寫模板的過程中,樣式風格已定並涉及更少的功能實現。
- 模板總是會被聲明的。
- 模板中任何 HTML 語法都是有效的。
- 閱讀起來更貼合英語(比如,for each item in items)。
- 不需要高級版本的 JavaScript 語法,來增加可讀性。
這樣,不僅開發人員更容易編寫代碼,設計人員和開發人員也可以更容易的分析代碼和貢獻代碼。
這還沒有結束。Vue 擁抱 HTML,而不是用 JavaScript 去重塑它。在模板內,Vue 也允許你用預處理器比如 Pug(原名 Jade)。
React 生態也有一個項目允許你寫模板,但是存在一些缺點:
- 功能遠沒有 Vue 模板系統豐富。
- 需要從組件文件中分離出 HTML 代碼。
- 這是個第三方庫,而非官方支持,可能未來核心庫更新就不再支持。
CSS 的組件作用域
除非你把組件分布在多個文件上(例如 CSS Modules),要不在 React 中作用域內的 CSS 就會產生警告。非常簡單的 CSS 還可以工作,但是稍微復雜點的,比如懸停狀態、媒體查詢、偽類選擇符等要么通過沉重的依賴來重做要么就直接不能用。
而 Vue 可以讓你在每個單文件組件中完全訪問 CSS。
<style scoped>
@media (min-width: 250px) {
.list-container:hover {
background: orange;
}
}
</style>
|
這個可選 scoped
屬性會自動添加一個唯一的屬性(比如 data-v-1
)為組件內 CSS 指定作用域,編譯的時候.list-container:hover
會被編譯成類似 .list-container[data-v-1]:hover
。
最后,就像 HTML 一樣,你可以選擇自己偏愛的 CSS 預處理器編寫 CSS。這可以讓你圍繞設計為中心展開工作,而不是引入專門的庫來增加你應用的體積和復雜度。
規模
向上擴展
Vue 和 React 都提供了強大的路由來應對大型應用。React 社區在狀態管理方面非常有創新精神(比如Flux、Redux),而這些狀態管理模式甚至 Redux 本身也可以非常容易的集成在 Vue 應用中。實際上,Vue 更進一步地采用了這種模式(Vuex),更加深入集成 Vue 的狀態管理解決方案 Vuex 相信能為你帶來更好的開發體驗。
兩者另一個重要差異是,Vue 的路由庫和狀態管理庫都是由官方維護支持且與核心庫同步更新的。React 則是選擇把這些問題交給社區維護,因此創建了一個更分散的生態系統。但相對的,React 的生態系統相比 Vue 更加繁榮。
最后,Vue 提供了Vue-cli 腳手架,能讓你非常容易地構建項目,包含了 Webpack, Browserify, 甚至 no build system。React 在這方面也提供了create-react-app,但是現在還存在一些局限性:
- 它不允許在項目生成時進行任何配置,而 Vue 支持 Yeoman-like 定制。
- 它只提供一個構建單頁面應用的單一模板,而 Vue 提供了各種用途的模板。
- 它不能用用戶自建的模板構建項目,而自建模板對企業環境下預先建立協議是特別有用的。
而要注意的是這些限制是故意設計的,這有它的優勢。例如,如果你的項目需求非常簡單,你就不需要自定義生成過程。你能把它作為一個依賴來更新。如果閱讀更多關於不同的設計理念。
向下擴展
React 學習曲線陡峭,在你開始學 React 前,你需要知道 JSX 和 ES2015,因為許多示例用的是這些語法。你需要學習構建系統,雖然你在技術上可以用 Babel 來實時編譯代碼,但是這並不推薦用於生產環境。
就像 Vue 向上擴展好比 React 一樣,Vue 向下擴展后就類似於 jQuery。你只要把如下標簽放到頁面就可以運行:
<script src="https://unpkg.com/vue/dist/vue.js"></script>
然后你就可以編寫 Vue 代碼並應用到生產中,你只要用 min 版 Vue 文件替換掉就不用擔心其他的性能問題。
由於起步階段不需學 JSX,ES2015 以及構建系統,所以開發者只需不到一天的時間閱讀指南就可以建立簡單的應用程序。
本地渲染
ReactNative 能使你用相同的組件模型編寫有本地渲染能力的 APP(IOS 和 Android)。能同時跨多平台開發,對開發者是非常棒的。相應地,Vue 和 Weex 會進行官方合作,Weex 是阿里的跨平台用戶界面開發框架,Weex 的 JavaScript 框架運行時用的就是 Vue。這意味着在 Weex 的幫助下,你使用 Vue 語法開發的組件不僅僅可以運行在瀏覽器端,還能被用於開發 IOS 和 Android 上的原生應用。
在現在,Weex 還在積極發展,成熟度也不能和 ReactNative 相抗衡。但是,Weex 的發展是由世界上最大的電子商務企業的需求在驅動,Vue 團隊也會和 Weex 團隊積極合作確保為開發者帶來良好的開發體驗。
MobX
Mobx 在 React 社區很流行,實際上在 Vue 也采用了幾乎相同的反應系統。在有限程度上,React + Mobx 也可以被認為是更繁瑣的 Vue,所以如果你習慣組合使用它們,那么選擇 Vue 會更合理。
Angular 1
Vue 的一些語法和 Angular 的很相似(例如 v-if
vs ng-if
)。因為 Angular 是 Vue 早期開發的靈感來源。然而,Augular 中存在的許多問題,在 Vue 中已經得到解決。
復雜性
在 API 與設計兩方面上 Vue.js 都比 Angular 1 簡單得多,因此你可以快速地掌握它的全部特性並投入開發。
靈活性和模塊化
Vue.js 是一個更加靈活開放的解決方案。它允許你以希望的方式組織應用程序,而不是在任何時候都必須遵循 Angular 1 制定的規則,這讓 Vue 能適用於各種項目。我們知道把決定權交給你是非常必要的。
這也就是為什么我們提供Webpack template,讓你可以用幾分鍾,去選擇是否啟用高級特性,比如熱模塊加載、linting、CSS 提取等等。
數據綁定
Angular 1 使用雙向綁定,Vue 在不同組件間強制使用單向數據流。這使應用中的數據流更加清晰易懂。
指令與組件
在 Vue 中指令和組件分得更清晰。指令只封裝 DOM 操作,而組件代表一個自給自足的獨立單元 —— 有自己的視圖和數據邏輯。在 Angular 中兩者有不少相混的地方。
性能
Vue 有更好的性能,並且非常非常容易優化,因為它不使用臟檢查。
在 Angular 1 中,當 watcher 越來越多時會變得越來越慢,因為作用域內的每一次變化,所有 watcher 都要重新計算。並且,如果一些 watcher 觸發另一個更新,臟檢查循環(digest cycle)可能要運行多次。Angular 用戶常常要使用深奧的技術,以解決臟檢查循環的問題。有時沒有簡單的辦法來優化有大量 watcher 的作用域。
Vue 則根本沒有這個問題,因為它使用基於依賴追蹤的觀察系統並且異步隊列更新,所有的數據變化都是獨立觸發,除非它們之間有明確的依賴關系。
有意思的是,Angular 2 和 Vue 用相似的設計解決了一些 Angular 1 中存在的問題。
Angular 2
我們單獨將 Augluar 2 作分類,因為它完全是一個全新的框架。例如:它具有優秀的組件系統,並且許多實現已經完全重寫,API 也完全改變了。
TypeScript
Angular 1 面向的是較小的應用程序,Angular 2 已轉移焦點,面向的是大型企業應用。在這一點上 TypeScript 經常會被引用,它對那些喜歡用 Java 或者 C# 等類型安全的語言的人是非常有用的。
Vue 也十分適合制作企業應用,你也可以通過使用官方類型或用戶貢獻的裝飾器來支持 TypeScript,這完全是自由可選的。
大小和性能
在性能方面,這兩個框架都非常的快。但目前尚沒有足夠的數據用例來具體展示。如果你一定要量化這些數據,你可以查看第三方參照,它表明 Vue 2 相比 Angular2 是更快的。
在大小方面,雖然 Angular 2 使用 tree-shaking 和離線編譯技術使代碼體積減小了許多。但包含編譯器和全部功能的 Vue2(23kb) 相比 Angular 2(50kb) 還是要小的多。但是要注意,用 Angular 2 的 App 的體積縮減是使用了 tree-shaking 移除了那些框架中沒有用到的功能,但隨着功能引入的不斷增多,尺寸會變得越來越大。
靈活性
Vue 相比於 Angular 2 則更加靈活,Vue 官方提供了構建工具來協助你構建項目,但它並不限制你去如何構建。有人可能喜歡用統一的方式來構建,也有很多開發者喜歡這種靈活自由的方式。
學習曲線
開始使用 Vue,你使用的是熟悉的 HTML、符合 ES5 規則的 JavaScript(也就是純 JavaScript)。有了這些基本的技能,你可以快速地掌握它(指南)並投入開發 。
Angular 2 的學習曲線是非常陡峭的。即使不包括 TypeScript,它的開始指南中所用的就有 ES2015 標准的 JavaScript,18個 NPM 依賴包,4 個文件和超過 3 千多字的介紹,這一切都是為了完成個 Hello World。而Vue’s Hello World就非常簡單。甚至我們並不用花費一整個頁面去介紹它。
Ember
Ember 是一個全能框架。它提供了大量的約定,一旦你熟悉了它們,開發會變得很高效。不過,這也意味着學習曲線較高,而且並不靈活。這意味着在框架和庫(加上一系列松散耦合的工具)之間做權衡選擇。后者會更自由,但是也要求你做更多架構上的決定。
也就是說,我們最好比較的是 Vue 內核和 Ember 的模板與數據模型層:
-
Vue 在普通 JavaScript 對象上建立響應,提供自動化的計算屬性。在 Ember 中需要將所有東西放在 Ember 對象內,並且手工為計算屬性聲明依賴。
-
Vue 的模板語法可以用全功能的 JavaScript 表達式,而 Handlebars 的語法和幫助函數相比來說非常受限。
-
在性能上,Vue 甩開 Ember 幾條街,即使是 Ember 2.0 的最新 Glimmer 引擎。Vue 能夠自動批量更新,而 Ember 在關鍵性能場景時需要手動管理。
Knockout
Knockout 是 MVVM 領域內的先驅,並且追蹤依賴。它的響應系統和 Vue 也很相似。它在瀏覽器支持以及其他方面的表現也是讓人印象深刻的。它最低能支持到 IE6,而 Vue 最低只能支持到 IE9。
隨着時間的推移,Knockout 的發展已有所放緩,並且略顯有點老舊了。比如,它的組件系統缺少完備的生命周期事件方法,盡管這些在現在是非常常見的。以及相比於 Vue 調用子組件的接口它的方法顯得有點笨重。
如果你有興趣研究,你還會發現二者在接口設計的理念上是不同的。這可以通過各自創建的 simple Todo List 體現出來。或許有點主觀,但是很多人認為 Vue 的 API 接口更簡單結構更優雅。
Polymer
Polymer 是另一個由谷歌贊助的項目,事實上也是 Vue 的一個靈感來源。Vue 的組件可以粗略的類比於 Polymer 的自定義元素,並且兩者具有相似的開發風格。最大的不同之處在於,Polymer 是基於最新版的 Web Components 標准之上,並且需要重量級的 polyfills 來幫助工作(性能下降),瀏覽器本身並不支持這些功能。相比而言,Vue 在支持到 IE9 的情況下並不需要依賴 polyfills 來工作,。
在 Polymer 1.0 版本中,為了彌補性能,團隊非常有限的使用數據綁定系統。例如,在 Polymer 中唯一支持的表達式只有布爾值否定和單一的方法調用,它的 computed 方法的實現也並不是很靈活。
Polymer 自定義的元素是用 HTML 文件來創建的,這會限制使用 JavaScript/CSS(和被現代瀏覽器普遍支持的語言特性)。相比之下,Vue 的單文件組件允許你非常容易的使用 ES2015 和你想用的 CSS 預編譯處理器。
在部署生產環境時,Polymer 建議使用 HTML Imports 加載所有資源。而這要求服務器和客戶端都支持 Http 2.0 協議,並且瀏覽器實現了此標准。這是否可行就取決於你的目標用戶和部署環境了。如果狀況不佳,你必須用 Vulcanizer 工具來打包 Polymer 元素。而在這方面,Vue 可以結合異步組件的特性和 Webpack 的代碼分割特性來實現懶加載(lazy-loaded)。這同時確保了對舊瀏覽器的兼容且又能更快加載。
而 Vue 和 Web Component 標准進行深層次的整合也是完全可行的,比如使用 Custom Elements、Shadow DOM 的樣式封裝。然而在我們做出嚴肅的實現承諾之前,我們目前仍在等待相關標准成熟,進而再廣泛應用於主流的瀏覽器中。
Riot
Riot 2.0 提供了一個類似於基於組件的開發模型(在 Riot 中稱之為 Tag),它提供了小巧精美的 API。Riot 和 Vue 在設計理念上可能有許多相似處。盡管相比 Riot ,Vue 要顯得重一點,Vue 還是有很多顯著優勢的:
- 根據真實條件來渲染,Riot 根據是否有分支簡單顯示或隱藏所有內容。
- 功能更加強大的路由機制,Riot 的路由功能的 API 是極少的。
- 更多成熟工具的支持。Vue 提供官方支持Webpack、Browserify和SystemJS,而 Riot 是依靠社區來建立集成系統。
- 過渡效果系統。Riot 現在還沒有提供。
- 更好的性能。Riot 盡管聲稱其使用了虛擬 DOM,但實際上用的還是臟檢查機制,因此和 Angular 1 患有相同的性能問題。
原文:http://vuejs.org/guide/comparison.html