JavaScript MVC框架PK:Angular、Backbone、CanJS與Ember

李鬆峰發表於2013-04-18

原文地址:http://sporto.github.io/.../comparison-angular-backbone-can-ember/
原文作者:Sebastian Porto @Twitter
本文譯者:@李鬆峰,感謝 @林永堅jake 推薦
版權宣告:經作者授權翻譯,轉載請註明原文及譯文出處

選擇JavaScript MVC框架很難。一方面要考慮的因素非常多,另一方面這種框架也非常多,而要從中選擇一個合適的,還真得費一番心思。想知道有哪些JavaScript MVC框架可以選擇?看看TodoMVC吧。

我用過其中4個框架:AngularBackboneCanJSEmber。因此,可以對它們作一比較,供大家參考。本文會涉及框架選型過程中需要考慮的一系列因素,我們逐一討論。

JavaScript MVC框架PK:Angular、Backbone、CanJS與Ember

JavaScript MVC框架PK:Angular、Backbone、CanJS與Ember JavaScript MVC框架PK:Angular、Backbone、CanJS與Ember JavaScript MVC框架PK:Angular、Backbone、CanJS與Ember

 
每一個因素我們都會按照1到5分來打分,1分代表很差,5分代表很好。我會盡量保持客觀,但也不敢保證真能“一碗水端平”,畢竟這些分數都是根據我個人經驗給出的。

功能

JavaScript MVC框架PK:Angular、Backbone、CanJS與Ember

作為構建應用的基礎,框架必須具備一些重要的功能。比如,檢視繫結、雙向繫結、篩選、可計算屬性(computed property)、髒屬性(dirty attribute)、表單驗證,等等。還能羅列出一大堆來。下面比較了一些我認為MVC框架中比較重要的功能:

功能AngularBackbone CanJSEmber
可觀察物件(observable)
路由(routing)
檢視繫結(view binding)
雙向繫結(two way binding)--
部分檢視(partial view)-
篩選列表檢視(filtered list view)-
  • 可觀察物件:可以被監聽是否發生變化的物件。
  • 路由:把變化通過瀏覽器URL的引數反映出來,並監聽這些變化以便執行相應的操作。
  • 檢視繫結:在檢視中使用可觀察物件,讓檢視隨著可觀察物件的變化而自動重新整理。
  • 雙向繫結:讓檢視也能把變化(如表單輸入)自動推送到可觀察物件。
  • 部分檢視:包含其他檢視的檢視。
  • 篩選列表檢視:用於顯示根據某些條件篩選出來的物件的檢視。

得分

根據上述功能,我打出的分數如下:

AngularBackbone CanJSEmber
5245

有一點必須指出,使用Backbone也能實現上述大多數功能,只是手工編碼量挺大的,有時候還要藉助外掛。這裡的打分只考慮了框架核心是否支援某一功能。

靈活性

enter image description here

有時候,框架配合一些現成的外掛和庫來使用,可能要比使用框架原生同類功能效果更好,而這種外掛和庫幾乎遍地都是(不下數百個),又各有特色。因此,能夠把這些庫和外掛整合到MVC框架中也非常重要。

Backbone是其中最靈活的一個框架,因為它的約定和主張最少。使用Backbone需要你自己作出很多決定。

CanJS的靈活性與Backbone差不多,把它跟別的庫整合起來很容易。在CanJS中甚至可以更換其他渲染引擎,我在CanJS中就一直用Rivets,沒有任何問題。不過,我還是推薦框架自帶的元件。

Ember和Angular也都還算靈活,可有時候你會發現,就算不喜歡它們的某些實現方法,你也只能默默忍受。 這是在選擇Ember或Angular時必須考慮的。

得分

AngularBackbone CanJSEmber
3543

上手難度

enter image description here

Angular

Angular一開始會讓人大呼過癮,因為可以利用它幹好多意想不到的事,比如雙向繫結,而且學習難度不高。乍一看讓人覺得很簡單。可是,進了門之後,你會發現後面的路還很長。應該說這個框架比較複雜,而且有不少標新立異之處。想看著它的文件上手並不現實,因為Angular製造的概念很多,而文件中的例子又很少。

Backbone

Backbone的基本概念非常容易理解。但很快你會發現它對怎麼更好地組織程式碼並沒有太多主張。為此,你得觀摩或閱讀一些教程,才能知道在Backbone中怎麼編碼最好。而且,你會發現在有了Backbone的基礎上,還得再找一個庫(比如MarionetteThorax)跟它配合才能得心應手。正因為如此,我不認為Backbone是個容易上手的框架。

CanJS

CanJS相對而言是這裡面最容易上手的。看看它只有一頁的網站(http://canjs.com/),基本上就知道怎麼做效率最高了。當然,還得找其他一些資料看,不過我個人很少有這種需求(比如看其他教程、上論壇或討論組提問呀什麼的)。

Ember

Ember的上手難度與Angular有一拼,我認為學習Ember比學習Angular總體上容易一些,但它要求你一開始就要先搞懂一批基本概念。而Angular呢,一開始不需要這麼費勁也能做一些讓人興奮不已的事兒。Ember缺少這種前期興奮點。

得分

AngularBackbone CanJSEmber
2453

開發效率

enter image description here

比較全面地掌握了一個框架之後,重點就轉移到了產出上。什麼意思呢?約定啊、戲法啊,反正要儘可能快。

Angular

熟悉Angular之後,你的效率會非常高,這一點毋庸置疑。之所以我沒給它打最高分,主要因為我覺得Ember的開發效率似乎更勝一籌。

Backbone

Backbone要求你寫很多樣板(boilerplate )程式碼,而我認為這完全沒必要。要我說,這是直接影響效率的一個因素。

CanJS

CanJS的開發效率屬於不快不慢的那種。不過,考慮到學習難度很低,因此適合早投入早產出的專案。

Ember

Ember的開發效率首屈一指。它有很多強制性約束,可以幫你自動完成的事很多。而開發人員要做的,就是學習和應用這些約定,Ember會替你處理到位。

得分

AngularBackbone CanJSEmber
4245

社群支援

enter image description here

能輕易找到參考資料和專家幫忙嗎?

Backbone的社群很大,這是人所共知的事實。關於Backbone的教程也幾乎汗牛充棟,StackOverflow和IRC社群非常熱鬧。

Angular和Ember社群也相當大,教程什麼的同樣不少,StackOverflow和IRC也很熱鬧,但還是比不上Backbone。

CanJS社群呢,相對小一些,好在社群成員比較活躍,樂於助人。我倒沒發現CanJS社群規模小有什麼負面影響。

得分

AngularBackbone CanJSEmber
4534

生態系統

enter image description here

有沒有外掛或庫構成的生態系統?

說起外掛和庫,Backbone的選擇是最多的,可用外掛俯拾皆是,這一點讓其他框架都望塵莫及。Angular的生態圈加上Angular UI還是很令人矚目的。我覺得Ember的下游生態雖然欠發達,但Ember本身很受歡迎, 所以前景十分樂觀。CanJS的下游支脈比較少見。

得分

AngularBackbone CanJSEmber
4524

檔案大小

enter image description here

這個因素有時候很重要,特別是對於移動開發專案。

自身大小(無依賴,未壓縮)

AngularBackbone CanJSEmber
80KB18KB33KB141KB

Backbone最小,這一點也是最為人們所津津樂道的。但不能只看庫本身的體積。

包含依賴的大小

80KB的Angular是唯一不需要其他庫就能使用的。其他三個框架則都對其他庫有依賴。

Backbone至少需要UnderscoreZepto。雖然在Underscore中可以使用最小的模板來渲染檢視,但多數情況下,還要藉助更好的模板引擎,比如Mustache。這樣它就增肥到了61KB。

CanJS至少需要Zepto,因此會達到57KB。

Ember需要jQueryHandlebars,總共是269KB。

AngularBackbone CanJSEmber
80KB61KB57KB269KB

得分

AngularBackbone CanJSEmber
4552

效能

enter image description here

我不認為效能是選擇框架的關鍵因素,因為這些框架在預期應用領域中的效能都不差。當然啦,具體還得看你做什麼專案。要是想開發遊戲,那效能是個重要因素。

雖然我見過,也親自做過一些效能對比(比如這個測試),但我並不完全相信測試結果。很難說這種測試的方法和結果與實際專案吻合。

不過,據我所見所聞,CanJS的效能是最高的,而且在檢視繫結上格外突出。相對來說,我覺得Angular效能稍差,因為它執行物件的髒檢查(dirty checking),這一點就拖了它的後腿了。參見這裡

得分

AngularBackbone CanJSEmber
3454

成熟度

enter image description here

這個框架成熟嗎,經過實際檢驗了嗎,有多少網站在用它呢?

使用Backbone的網站不計其數。最近兩年,它的核心程式碼沒怎麼改過,這是成熟的一個重要標誌。

Ember已經不是新框架了,但它的重大變更還是經常有,前幾月剛剛穩定下來。因此,目前還不能說它是個成熟的框架。

Angular似乎比Ember更穩定,驗證的示例也更多,但不能與Backbone相提並論。

CanJS好像還未經任何驗證,因為不知道有什麼網站在使用它。不過,CanJS其實也沒有看起來那麼弱不經風,它可是從JavaScriptMVC精簡來的。JavaScriptMVC是2008年就出現的一個庫,因此會有很多智慧結晶留傳下來。

得分

AngularBackbone CanJSEmber
4543

記憶體洩漏隱患

如果你想開發每次開啟都得執行很長時間的單頁應用,這是必須得考慮的問題。你當然不希望自己的應用導致記憶體洩漏,這個問題非常現實。不幸的是,記憶體洩露很容易發生,而自己編寫的DOM事件監聽器則是重災區。

只要你守規矩,Angular、CanJS和Ember能把這個問題幫你解決好。Backbone則不然,它需要你自己手工來解除安裝。

得分

AngularBackbone CanJSEmber
5355

個人偏好

這恐怕是選擇框架時最重要的一個因素了。

  • 你喜歡宣告式HTML嗎?-> Angular
  • 你喜歡使用模板引擎嗎?-> Backbone、CanJS或Ember
  • 你喜歡固執已見的框架嗎?-> Ember
  • 你希望框架與最初的SmallTalk MVC模式完全吻合嗎?-> 沒有完全吻合的,或許CanJS最接近
  • 你希望使用目前看來很酷的框架嗎?-> Ember、Angular

本項沒辦法打分。

算總分

好啦,把各框架所得分數做個彙總吧。別忘了這只是我個人看法,如果你覺得哪一項打分有失偏頗,請務必告訴我。

(此處只是一個靜態圖表,單擊可以開啟) JavaScript MVC框架PK:Angular、Backbone、CanJS與Ember

如果每一個因素的權重都一樣,那麼這幾個框架確實難分高下。因此,我覺得最終決定很大程度上還是取決於你的個人偏好,或者必須要給每個因素賦予不同的權重才行。

聊聊Backbone(公平到此為止!)

我在這篇文章裡始終儘量做到“一碗水端平”。可是,最後針對Backbone我還想再多說兩句,因為這些話如鯁在喉,不吐實在不快。

Backbone在兩年前是一個不錯的庫,但我知道:今天已經有了更好的選擇了。我也知道,很多人選擇Backbone其實僅僅因為使用它的人多,這是個惡性迴圈。

Backbone為追求靈活性而拋棄了開發的便利性。但我覺得它實在太過了,功能嚴重缺乏,導致開發效率很低。沒錯,有一大堆外掛可以實現這樣那樣的功能,可這樣一來你不僅要學習Backbone,還得不斷學習怎麼使用那些外掛。

Backbone的大型社群和生態系統也很誘人,但隨著其他框架越來越受歡迎,這個優勢也將慢慢消失。

正因為如此,我強烈建議大家選擇Backbone時要三思而後行。

2013-04-18更新:澄清一下,最後一節只代表我的觀點。另外也刪除了“現在該拋棄(Backbone)”那句話,有人說太過激了。


相關文章