Angular.js VS. Ember.js:誰將成為Web開發的新寵?
本文源自于Quora網站的一個問題,作者稱最近一直在為一個新的Rails項目尋找一個JavaScript框架,通過篩選,最終糾結于 Angular.js和 Ember.js。
這個問題獲得了大量的關注,并吸引到這兩個框架的開發者參與回答。如果你也糾結JavaScript框架的選擇,那么本文對你來說也是一個非常好的參考資料。
Angular.js和Ember.js介紹
Angular.js是一款開源的JavaScript框架,由Google維護,其目標是增強基于Web應用,并帶有MVC功能,使得開發和測試變得更加容易。
Angular.js讀取包含附加自定義(標簽屬性)的HTML,遵從這些自定義屬性中的指令,并將頁面中的輸入輸出與由JavaScript變量表示的模型綁定起來。這些JavaScript變量的值可以手工設置,或者從靜態或動態JSON資源中獲取。
項目地址: http://angularjs.org/
Ember.js同樣是一個用于創建web應用的JavaScript MVC 框架,其采用基于字符串的Handlebars模板,支持雙向綁定、觀察者模式、計算屬性(依賴其他屬性動態變化)、自動更新模板、路由控制、狀態機等。
Ember.js使用自身擴展的類來創建Ember.js對象、數組、字符串、函數,提供大量方法與屬性用于操作。每一個Ember.js應用都使用各自的命名空間,避免沖突。
項目地址: http://emberjs.com/
Angular.js開發者:Angular.js最能體現HTML的精髓
Angular.js其中一位開發者Misko Hevery回復了提問者的疑問,內容如下。
我是Angular團隊中的一名開發者,我還不太了解Emeber.js,因此我的觀點可能會有些偏頗。
有人說,Angular.js和Ember.js都在HTML中放入了太多的邏輯。當然,將邏輯放入HTML是一個不好的做法,我們也不建議這么 做。事實上,Angular.js只放置綁定,而不是邏輯,我們建議把邏輯放入控制器中。但綁定同樣是信息,這些信息可以放在一些地方,你有三種選擇:
- 代碼。但這使得程序模塊化很成問題,因為HTML與代碼緊密耦合,要想重新組成一個應用程序非常困難。
- HTML。這正是Angular.js所做的。我們認為,除了放置連接信息外,你不應該在HTML中做任何事情。任何邏輯都不應該出現在這里,因為它會導致各種問題。我認為Angular.js做的綁定相當好。
- 元數據文件:雖然我不知道是否有人這樣做,但基本上這是一個雙重問題,因為你將不得不在代碼中連接HTML位置和模型位置。
當然,在構建一個應用程序時,你也可以不使用框架,但不可否認,使用框架將使得你的開發工作變得更容易。
我個人認為Angular.js的獨特之處在于它擁抱HTML/CSS,遵循“HTML是什么”的精神。其他一些框架提供了它們自己的API,偏 離了HTML。Angular.js在所有框架中是最能體現聲明式的。我相信聲明式非常適合用來構建用戶界面,而JS非常適合用來編寫邏輯。
Angular.js允許你擴展HTML,所以你在使用Angular.js過程中遇到的任何問題都可以很容易地克服。你可以在Angular.js官網中 http://angularjs.org找到一些能夠展示其特性的例子。
Ember.js開發者:Ember.js是構建“雄心勃勃”的應用程序的不二選擇
Ember.js的一位開發者Tom Dale對Angular.js和Ember.js進行了詳細對比,具體內容如下。
作為Ember.js的作者之一,我經常會被問道:應該使用Angular.js還是Ember.js?
我認為在做出選擇之前,需要考慮:要構建什么樣的應用?那么Ember.js是不是比Angular.js更好呢?
雖然兩者在表面上有一些相似之處——它們都使用綁定,都比其他框架(比如Backbone.js)更有利于編寫Web應用程序。
我首先來介紹一下Ember.js項目的由來。從2009年開始,我就一直在蘋果公司參與 SproutCore的開發,這是一個開源的類似于Cocoa的JavaScript框架,后來演變成了你現在所看到的 iCloud。當時,我的周圍是一些世界上最好的Cocoa開發者。
問題是,多少年來在客戶端應用程序方面,似乎并沒有真正新的突破。自80年代以來就一直遵循的基本模型——代碼運行在本地計算機上,從網絡上獲取 數據,然后在本地處理,并顯示在屏幕上;而如今唯一改變的是——代碼運行在瀏覽器的沙箱環境中,然后加載所需的“二進制”文件,而不是由用戶安裝到硬盤上 的文件。
在考慮這些問題是,我會首先想到:在我們之前,人們已經做了什么?我認為很難去爭辯框架的成功,比如Cocoa,無論在Mac還是iOS上,Cocoa都可以讓開發者輕松編寫受用戶喜愛的應用程序。
我們希望開發者能夠創建雄心勃勃的、能夠與本地應用競爭的Web應用程序。要做到這一點,開發者首先需要先進的工具和正確的概念,以幫助他們溝通和協作。
在開發Ember.js過程中,我們花了大量時間從其他一些本地應用程序框架(如Cocoa)中引入一些概念,但后來我們感覺到這些概念帶來的困 擾多于幫助,或它們并不適合用來構建Web應用程序。因此,我們開始轉向其他流行的開源項目,比如Ruby on Rails和Backbone.js,從它們中來找靈感。
因此,Ember.js最終成為了一個綜合的、強大的、符合現代Web特性的、輕量級的工具。
在我看來,與Ember.js相比,Angular.js更像一個研究項目。比如,來看看它們的學習文檔:Ember.js主要討論模型、視圖和控制器,而Angular.js指南要求你去學習一些類似于范圍、指示符和transclusion方面的內容等。
我完全支持一些研究型項目,并希望它們能夠變成最好的。但是,要記住,要在生產環境中看待應用程序。
一些大公司已經在Ember.js上投入了時間和精力,比如新版ZenDesk已經使用Ember.js重寫(在他們對Backbone.js失 望后,決定放棄它改用Ember.js),Square的整個Web層面也是基于Ember.js的(因為他們想要一個漂亮、響應式的 UI),Groupon的移動版Web應用也是使用Ember.js開發的。此外,還有很多初創型公司通過Ember.js獲得了成功,并開始對 Ember.js社區進行貢獻。
而我目前所看到使用Angular.js開發的大多數應用程序只是演示項目,或是Google的內部項目。
Yehuda(Ember.js開發者之一)和我也一直積極邀請真正的用戶參與Ember.js框架的設計和維護,這可以確保我們在Ember.js中添加的功能對于實際開發是有用的。
事實上,在過去的幾個月中,大多數Ember.js開發工作都是由Ember.js社區的核心貢獻組完成的,他們來自不同的公司。如果 Yehuda和我哪天有什么事情,或者我們的公司倒閉了,Ember.js還將會持續發展。這是一個真正的社區項目,而不是“Google”項目。
回到技術細節。Angular.js官網上寫道“Angular.js是HTML的未來,它被設計用于構建Web應用程序。”我認為當看他們的應 用程序時,這種理念是顯而易見的——用戶界面由HTML標記定義,使用有語義意義的屬性(比如data-ng-repeat)來裝飾。
而Ember.js使用Handlebars來描述HTML,來展現你的應用程序界面。從美觀角度,我們可以談談你是更喜歡Handlebars 語法(使用類似于{{#each}}的helper),還是喜歡像Angular.js那樣通過額外的屬性來注釋HTML。我個人認為,HTML屬性方法 有點雜亂,難以閱讀。當然,你可以使用其中任何一種方式。如果Ember.js不存在,而我又必須使用一個使用了數據屬性的框架,那么我會考慮 Angular.js。
拋開美觀不談,我相信,Ember.js使用基于字符串的模板的方式也為我們帶來了一些優勢:
- 基于字符串的模板可以在服務器上預編譯。這樣可以減少啟動時間,也意味著渲染一個模板可以像調用一個函數一樣簡單。
- Angular.js需要你在應用程序啟動時遍歷整個DOM,你的應用程序越大,啟動速度越慢。
- 如果你想在服務器上渲染你的應用程序(用于Google爬蟲索引或讓首次加載時顯示速度更快),Angular.js需要你去啟動整個 瀏覽器環境,像PhantomJS,這是資源密集型的。而Handlebars是100%的JavaScript字符串,所有你需要的只是像 node.js或Rhino之類的東西。
- 如果你的應用程序變得越來越大,那么字符串模板可以很容易地被分割和懶加載。
此外,Handlebars只讓你綁定屬性,而Angular.js允許你嵌入實時更新的任意表達式。很多人最初將這個視為Ember.js的局限性,但實際上:
- Ember.js允許非常容易地使用JavaScript來創建可計算屬性,它可以包含任意表達式。我們只要求你指定你的依賴,這樣在更新時可以智能些。
- Angular.js在每次有新的變化時,必須重新計算這些表達式,這意味著需要在你的應用程序中綁定更多的元素,速度會變慢。
- 因為Ember.js只允許你綁定屬性,我們將可以很容易地利用ECMAScript 6的性能優勢,如Object.observes。由于Angular.js發明了自己的帶有 自定義解析器的JavaScript子集,這對于瀏覽器來說,優化代碼變得比較困難。
在一般情況下,Angular.js依靠一種叫做“ 臟檢查(dirty checking)”的機制來確定對象是否已進行更改。“臟檢查”的方式是,在你掃描每個對象和其所有綁定屬性時,比較當前值和之前已知的值。如果它發生 了變化,你就需要去更新其綁定。正如你能想到的那樣,代碼中對象越多,成本將越昂貴。
但Angular.js開發者非常聰明,他們非常仔細地進行了折中。他們的方案是:
- 使用“臟檢查”,你不需要使用accessors。你可以用person.name = "Bill"來代替person.set('name', "Bill"),就像在Ember.js 或 Backbone.js中的一樣。
- 為什么在DOM中你會有這么多的對象?這最終將會成為一個瓶頸的。
Miško Hevery在StackOverflow上介紹了 這種折中方式。他指出,使用“臟檢查”,你無法一次有超過2000個綁定對象。
我認為這很好地說明了Ember.js 和 Angular.js理念上的區別。Ember.js 和 Angular.js都力求簡單和易用。而Ember.js使你不必擔心代碼中是否有超過2000個綁定。如果你正在編寫大型應用程序,那么你已經解決了 你所擔心的最大的事情。對于中小規模的應用程序來說,Angular.js同樣是偉大的,因為這些應用程序不會觸及Angular.js的限制區。
在Ember.js中,我們總是希望利用瀏覽器和語言中的新功能,以便使事情變得更容易。例如,一旦ES6中 代理對象(proxies)可用,我們不會再要求你使用get()和set()。
所以這就是為什么我認為——如果你想構建雄心勃勃的應用程序,你應該選擇Ember.js。
我們從不拒絕從其他一些框架中吸取一些知識,因為這些框架已經知道如何最好地去構建大型應用程序。
我們已經有了一個夢幻般的社區,有一群最聰明的Web開發人員,他們致力于解決現實中遇到的最難的一些問題。
此外,在開發過程中,我們對于性能方面和如何利用語言新特性方面也考慮了很久。Yehuda Katz和我一起開發Ember.js,他同時也是TC39(負責JavaScript下一個版本的制定)的成員,在此方面相當有經驗。
我們已經發布了1.0版API,因此你可以開始學習,而不用擔心有大的變化。
你可以通過這個視頻來了解如何通過Ember.js從頭開始構建一個應用程序: Building an App with Ember.js
下面是一些非常棒的學習資源:
- Ember.js指南
- Rey Bango的 Ember.js入門教程
- Luke Melia 的 介紹Ember.js幻燈片
如果你想構建一個雄心勃勃的應用程序,你一定要考慮Ember.js。
angularjs_scaffold開發者:Angular.js符合Web的未來
angularjs_scaffold的開發者Patrick Aljord也參與了討論,內容如下。
我是 angularjs_scaffold(基于Angular.js編寫的針對scaffolding視圖的Rails插件)的開發者,我來說說為什么我會選擇Angular.js。
事實上,我原本打算在項目中使用Ember.js,因為我比較信賴Yehuda(Ember.js開發者之一)在Rails和jQuery方面的 工作。但是Ember.js中隨時會變化的API和匱乏的文檔,使我一再推遲使用它。我偶然發現了Angular.js,就被它吸引了。
像Tom Dale(Ember.js開發者之一)所說,Ember.js受Cocoa 和Rails啟發。但問題是,通過Ember.js,我并沒有真正感覺到像在寫一個Web應用程序,它就像一堆拋出的概念。而在Angular.js中, 我感覺像在寫一個Web應用程序,它真正支持所有的Web概念,并以一種非常自然的方式來擴展HTML。
事實上,Angular.js并沒有使用自己的對象或重寫JS方法,當你使用Angular.js時,你就使用了純JS,并且Angular.js實現的許多概念都將直接進入下一個版本的Javascript中。
學習Angular.js,就意味著學習未來的Javascript,而學習Ember.js,你只是學習到了Ember的特定概念。
來看個例子。HTML是偉大的,因為它是聲明式的,如果想要定義一個段落,你只需寫如下代碼:
- <p>Hello world</p>
但是如果你想非常動態地實現?你需要通過類似于下面的代碼來引導瀏覽器:
- <p id="greeting1"></p>
- <script>
- var isIE = document.attachEvent;
- var addListener = isIE
- ? function(e, t, fn) {
- e.attachEvent('on' + t, fn);}
- : function(e, t, fn) {
- e.addEventListener(t, fn, false);};
- addListener(document, 'load', function(){
- var greeting = document.getElementById('greeting1');
- if (isIE) {
- greeting.innerText = 'Hello World!';
- } else {
- greeting.textContent = 'Hello World!';
- }
- });
- </script>
來看看Angular.js如何實現:
- <p>{{hello}}</p>
它通過HTML聲明來編寫動態代碼。再來看一個示例,如果你要遍歷一個數組,只需:
- <ul>
- <li ng-repeat="element in array">element</li>
- </ul>
這個語法看起來像新的 MDV標準。這看起來比Ember.js更加簡潔。另外,Angular.js被優化得非常快,開發團隊通過如下措施來實現:
- 臟檢查
- 只檢查當前視圖
- 只在變化發生時檢查
- 通過和Chrome團隊協作來利用JIT
在一些基準測試中,結果顯示Angular.js的速度要快于Ember.js,具體可見 Angular VS Knockout VS Ember。
Angular.js未來會擁有可重用的組件,這允許你編寫非常簡潔的代碼,并輕松重用一些部件。這不是Angular.js特定的需求,而是Web的未來。
此外,Angular.js還擁有一個龐大的社區和 大量的貢獻者。