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