AngularJS 、Backbone.js 和 Ember.js 的比較

1 介紹

  咱們準備在這篇文章中比較三款流行於Web的「模型-視圖-*」框架:AngularJS、Backbone和Ember。爲你的項目選擇正確的框架可以對你及時交付項目的能力和在之後維護你本身代碼的能力產生巨大影響。你也許想基於一款可靠的、穩定的和成熟的框架來構建項目,但又不想爲此受到約束。Web發展迅速——新技術產生,舊的那套方法很快跟不上潮流。如此形勢之下,咱們準備仔細深刻的比較這三個框架。javascript

 2  框架概覽

  今天咱們提到的全部框架有許多共同點:都是開源的,聽從 MIT 協議,而且都嘗試經過 MV* 模式來解決開發單頁面應用的問題。它們都有相似的概念:視圖,事件,數據模型和路由。咱們先簡單回顧一下有關的歷史和背景知識,而後再展開深刻比較這三款框架。html

  AngularJS 誕生於 2009 年,當時做爲一個大型商業產品的一部分叫作 GetAngular。不久以後,Misko Hevery,GetAngular 項目建立者之一,花了僅僅三週時間,用 GetAngular 重寫了一個曾經耗時 6 個月才完成的,有 17K 行代碼的頁面應用,並將代碼削減到 1,000 行左右,因而成功的說服了谷歌開始贊助該項目,並將其開源,也就是咱們今天看到 AngularJS 。Angular 的特色是擁有雙向數據綁定,依賴注入,易於測試的編碼風格,以及經過使用自定義指令能夠簡單的擴展 HTML。java

  Backbone.js 是一個輕量級的 MVC 框架。誕生於 2010 年,它做爲那種笨重全功能的 MVC 框架,好比說 ExtJS, 的一個代替品,迅速流行開來。 不少服務都使用了它,好比 Pinterest, Flixster, AirBNB 等等。程序員

  Ember 則要回溯到 2007 年,最開始是以 SproutCore MVC 框架展示在世人面前,由 SproutIt 開發,後來是 Apple,再後來到 2011 的時候,jQuery 和 Ruby on Rails 的核心貢獻者 Yehuda Katz 參與了進來。有名的 Ember 用戶包括了 Yahoo!, Groupon, 和 ZenDesk。angularjs

 3 社區

  社區是在選擇一個框架的時候,要考慮的最重要因素之一。大社區意味着更多的答案,更多的第三方模塊,更多的 YouTube 教程…你,明白了麼。我作了個統計,截止 2014年8月16日,Angular 是絕對的王者,做爲 GitHub 上第六大星級項目,在 StackOverflow 上的提問比 Ember 和 Backbone 加起來還多,你本身看:web

Github 的點贊星數 27.2k 18.8k 11k
第三方模塊 800 ngmodules 236 backplugs 21 emberaddons
棧爆網的提問件數 49.5k 15.9k 11.2k
YouTube 件數 ~75k ~16k ~6k
GitHub 貢獻者 928 230 393
Chrome 插件用戶 150k 7k 38.3k
指標 AngularJS Backbone.js Ember.js

  全部這些指標,顯示的僅僅是每一個框架的當前狀態。看看哪一個框架增加最快也是頗有趣的,你有福了,經過穀人希的趨勢跟蹤,你能夠獲得如下答案:編程

  http://www.google.com/trends/explore?hl=en-US#q=ember.js,+angularjs,+backbone.js&cmpt=q緩存

 4 框架大小

  頁面的加載時間是你網站成功的關鍵。當涉及瀏覽速度的時候,用戶沒太多耐性 — 因此不少狀況下你要儘量讓你的應用跑得越快越好。使用框架,有兩個因素會對應用的加載時間產生影響: 框架的大小和它啓動的時間。網絡

  Javascript 資源一般都會被通過精簡和壓縮,因此咱們來比較一下壓縮版。可是隻看框架的大小確定不夠的。Backbone.js,儘管是最小的 (只有 6.5kb),可是必須 Underscore.js (5kb) 和 jQuery (32kb) 或者 Zepto (9.1kb),並且你還有可能還有一些第三方插件要加進來。框架

AngularJS 1.2.22      39.5kb      39.5kb
Backbone.js 1.1.2      6.5kb      43.5kb (jQuery + Underscore)
     20.6kb (Zepto + Underscore)
Ember.js 1.6.1      90kb     136.2kb (jQuery + Handlebars)
框架     淨大小      包含依賴以後的大小

 5 模板

  Angular 和 Ember 都有模板引擎。而另外一方面 Backbone,把這個選擇權留給了你。感覺模板引擎的異同最好的辦法就是上點代碼,好的,咱們開始。咱們將演示把一個列表轉換成 HTML 列表的例子。

  5.1 AngularJS

  Angular 的模板引擎僅僅是在 HTML 上使用綁定表達式。而綁定表達式又僅僅是兩層大括號而已:

<ul>
  <li ng-repeat="framework in frameworks" 
      title="{{framework.description}}">
    {{framework.name}}
  </li>
</ul>

  5.2 Backbone.js

  Backbone 能夠和許多第三方模板引擎集成,默認的選擇是 Underscore 模板。 由於 Underscore 是 Backbone 的依賴項,你已經把它加載到頁面中了,你無須添加任何額外的依賴關係就可使用它的模板引擎。不爽的是,Underscore 的模板引擎很是初級,你一般不得不把 javascript 混進去,好比說:

<ul>
  <% _.each(frameworks, function(framework) { %>
    <li title="<%- framework.description %>">
      <%- framework.name %>
    </li>
  <% }); %>
</ul>

  5.3 Ember.js

  Ember 目前用的是 Handlebars 模板引擎,熱門的 Mustache 模板引擎的擴展。一個新的 Handlebars 變種,叫作 HTMLBars ,目前已經可使用了。Handlebars 不關心 DOM – 它所作的僅僅是作一個簡單的字符串變換。而 HTMLBars 則能夠處理 DOM,全部的變量轉換都有上下文感知。因爲 HTMLBars 尚未流行,咱們仍是來看看用 Handlebars 方式打印列表方式:

<ul>
  {{#each frameworks}}
    <li {{bind-attr title=description}}>
      {{name}}
    </li>
  {{/each}}
</ul>

 6 AngularJS

  6.1 好處

  Angular 爲 Web 開發帶來了許多創新的概念。雙向數據綁定節省了大量的樣板代碼。好比下面的 jQuery 代碼片斷:

$('#greet-form input.user-name').on('value', function() {
    $('#greet-form div.user-name').text('Hello ' + this.val() + '!');
});

  因爲 Angular 的雙向綁定,你根本就不須要本身寫代碼。只須要在 HTML 模板裏面聲明綁定就能夠了:

<input ng-model="user.name" type="text" />
Hello {{user.name}}!

  Promises 在 Angular 中扮演了一個重要的角色。Javascript 是單線程,基於事件循環的語言,這意味着許多操做(好比說網絡通信)都是以異步方式進行的。異步的 Javascript 代碼會很快的就陷入了長長的嵌套回調,也就是臭名昭著的 「Pyramid Code」 或者叫作 「Callback Hell」。

  相對比另外兩個,Angular 不光有着更大的社區,更多的在線文檔,並且還有谷歌在背後的推廣和支持。因此,核心團隊還在不斷增加,產出更多的創新,以及改善開發生產效率的工具,好比: Protractor, Batarang, ngmin 和 Zone.js,一抓一大把。並且,開發團隊還向用戶徵集需求。好比說,Angular 2.0 的全部設計文檔你均可以從 這裏 找到,任何人均可以直接給設計文檔提建議。

  Angular 幫助你把構建應用的程序塊劃分爲下面這幾種類型:控制器(Controller),指令(Directive),工廠(Factory),過濾器(Filter),服務(Service)和視圖(View) (就是模板)。它們被組織爲模塊形式,以後能夠被另外一個引用。每種類型有不一樣的做用。視圖處理 UI,控制器處理 UI 背後的邏輯,服務用來處理和後臺的通訊,而且將共通的有關聯的功能組件結合在一塊兒,而指令經過定義新的元素,屬性和行爲,很容易的構造可重用的組件,以及HTML擴展。

  自動髒值檢查意味着,你不須要用 getter 和 setter 去訪問數據模型 — 你能夠修改任意範圍(scope)的任意屬性,而後 angular 會自動檢測到變化,通知該屬性的全部觀察者(watcher)。

  「Angular 的初衷是寫出可測試的代碼。」 單元測試指南中的這句話,包含了太多意思 – Angular 確實很注重分離,單元隔離,爲 $http 和 $timeout 等基礎內置服務提供了現成的,強大的 mock。

  6.2 痛處

  Angular 常被人詬病的是指令那複雜的 API。 Transclusion,尤其突出,這個概念,把許多開發者搞得一頭霧水,讓你滿腦子各類概念,好比編譯函數(compiling function),linking,函數的預處理/後處理(pre/post linking functions),各類 scope 類型 (transclusion/isolate/child scope),還有各類配置設置,須要至關的時間來掌握。

  Angular 中的 scope 層次結構使用的是 Prototypal 繼承,這又是一個爲了迎合從面嚮對象語言,好比 Java 和 C#,過來的開發人員而提出的概念。不理解 scope 致使許多開發者開發很受傷 (好比說: 這, 這 還有這)。

  Angular 表達式 在視圖層被普遍應用。表達式語言很是強大,有時候是強大過頭了。這誘導開發者使用各類複雜的邏輯,甚至執行賦值運算和計算所有都放在模板中。把邏輯運算放在模板中讓它很是難以測試,由於它變成不可能獨立測試了。看看下面的例子,演示瞭如何濫用這種模板語言的:

<button ng-click="(oldPassword && checkComplexity(newPassword) && oldPassword != newPassword) ? (changePassword(oldPassword, newPassword) && (oldPassword=(newPassword=''))) : (errorMessage='Please input a new password matching the following requirements: ' + passwordRequirements)">Click me</button>

  許多狀況下,指令名稱的拼寫錯誤,或者調用未定義 scope 方法,都會被忽略,而且很難被發現,特別是當你把複雜的指令 API 和上面提到的 scope 的繼承弄到一塊兒的時候。我見過有些苦逼花費一大堆時間抓耳撓腮想找出爲何 scope 中的一個綁定的事件沒被回調函數觸發,最後竟然是由於用了駝峯(camelCase)命名,而沒有用連字符分隔(hyphen-separated)拼寫屬性的名稱(好比說這).

  最後,是 Angular 的循環系統中, 要注意那「神奇的」髒值檢查,它常常會給開發者驚喜。在非-Angular上下文運行的時候,很容易忘記調用 $digest() (例子)。也就是說,你必須很是當心,不要觸發緩慢的觀察者事件或者無限循環(例子: 這, 這 還有 這)。一般,對於一頁上有大量的交互元素的頁面,Angular會變得很是慢。有個很好的界定是,不要在同一頁面上放超過 2,000 個活動的綁定。

 7 Backbone.js

  7.1 好處

  Backbone 輕量,快速,內存佔用小。學習曲線也是很平緩的,只須要幾個簡單的概念就能掌握 (模型/集合, 視圖, 路由)。它有很棒的文檔,代碼簡單,註釋詳細,而且這裏還有一個註釋版源碼,用來解釋框架的工做細節。實際上你能夠通讀整個框架的源碼,用不到一個小時去熟悉它。

  由於又小又基礎,你能夠基於 Backbone 打造你本身的框架。一些基於 Backbone 的第三方框架的例子有 Aura, Backbone UI, Chaplin, Geppetto, Marionette, LayoutManager, Thorax, Vertebrae。用 Angular 和 Ember 你通常都要用框架做者給你的選擇,有些可能會不適合你的工程需求和我的風格。Angular 2.0 承諾改變這種狀況,經過構建更小的獨立模塊,使你能夠選擇和組合它們。不過咱們還沒看到它何時才能交付。

  7.2 痛處

  Backbone 沒有提供基本構造。它僅僅是提供了一些基礎工具讓你去建立,讓你去決定如何構造應用,這有太多空要填了。好比說內存管理須要當心的處理。因爲缺失視圖生命週期管理,這會使得路由/狀態的變化,很容易致使內存泄漏,除非你能夠很清楚的處理一切。

  誠然,Backbone自己不提供的功能,能夠由第三方插件來填補,這也就意味着,在你建立應用的時候,有不少選擇,由於一個功能一般有許多個備選插件。好比說,內嵌模型能夠由下面這些插件提供:Backbone.DocumentModel, BackBone.NestedTypes, Backbone.Schema, Backbone-Nested, backbone-nestify, 這仍是其中的一小部分。決定哪一個更適合你的工程是須要調查的,這須要時間 — 而使用框架的一個主要目的是節省你的時間。

  Backbone 缺少對雙向數據綁定的支持,意思也就是說,你必須編寫大量的樣板來處理模型更新以後觸發的視圖更新。看看上面給出的例子,想一想看 Angular.js 的雙向數據綁定削減了多少樣板代碼。

  Backbone 中的視圖是直接操做 DOM 的,這讓它們很是難作單元測試,也就更脆弱,更難以重用。常見的例子就是用 CSS 選擇器查找 DOM 元素,改變CSS 類名,添加有一樣類名的新元素或者把一樣的 DOM 樹包裝到另外一個元素,都會打亂你的 CSS 選擇器以及應用的渲染。

 8 Ember.js

  8.1 好處

  Ember.js 主張約定優於配置。也就是說,無需編寫大量的樣板代碼,Ember 會自動推導出許多配置自己,好比在定義一個路由資源的時候,能夠自動斷定路由的名稱和控制器。Ember 甚至會在你沒定義控制器的時候,自動爲你的資源生成一個。

  Ember 包含了一個優秀的路由和一個可選的數據層,叫作 ember data。和其餘兩個框架不一樣,它們的數據層很是小(Backbone 的集合/模型和 Angular 的 $resource),Ember 有一個拿來即用的很是成熟的數據模塊,只須要簡單的配置,就能夠和後臺的 Ruby-on-Rails 或者其它的 RESTful JSON API 集成得很是好。它還能夠經過設置 fixtures來支持面向 mock API 開發以及測試。

  性能是 Ember.js 設計的主要目標。諸如 The Run Loop 這個概念,能夠確保數據的變化只致使單個 DOM 更新,即便同一塊數據進行了屢次更新也是同樣,還有計算屬性的緩存, 還有能夠在編譯時或在服務端對 HandleBars 模板進行預編譯的能力,均可以幫助你保證應用的負載,保證它跑得足夠快。

  8.2 痛處

  Ember 的 API 在它穩定版出來以前變化太大了。這致使了有大量的過時內容和不能再運行的例子,這會新進開發者開始使用這個框架時感到很是困惑。看看 Ember Data 變動日誌,你就會知道我說的是什麼意思了。這裏有太多的大變動了,這就讓許多棧爆網的回答和編碼例子變得毫無心義了(好比說這)。

  Handlebars 爲了保持模板和數據模型一致,用了太多的 <script> 標籤來污染 DOM 了。這會在遷移到 HTMLBars 的時候變得毫無心義,但到那時,你的 DOM 樹上全都是 <script> 標籤,會幾乎沒法辨認哪些是你的代碼了。還有最糟糕的部分 – 這會打亂你的CSS樣式,或者影響和其餘框架的集成,好比說 jQuery UI 的排序。

 9 總結

  咱們已經看過三個框架的長處短處。Ember 的綜合能力,其中的 MVC 結構,對於那些曾經在 Ruby, Python, Java, C# 或者其餘面嚮對象語言中有過 MVC 編程背景知識的程序員來講很是有意義。Ember 還帶來了媲美桌面應用的性能,並且還由於約定優於配置的緣由,可讓你節省很是多樣板代碼。

  Backbone 崇尚極簡主義。它夠小,夠快,夠簡單,可是提供了你構建應用所須要的最小集(許多狀況下,甚至要小於最小集)。

  Angular 的擴展 HTML 的創新方法,對於骨子裏是 web 開發者的人來講很是有意義。它有強大的社區,有谷歌在後面支持它,它不斷沉澱和成長。它不但適用於快速原型開發,還適用於大型生產應用。

 

原文:https://www.airpair.com/js/javascript-framework-comparison

相關文章
相關標籤/搜索