2012年7月12日 星期四

Top 10 Javascript MVC Framework and Single Page Application




前一陣子連Blogger也開始使用SPA(Single Page Application)的作法,也就是動態檢視(Dynamic View)的功能,在Chrome的執行下的換頁特效非常地順暢。我並不清楚是否運用server side to client javascript,如同GWT一樣,能否方便撰寫這種架構的軟體?不過我很清楚的是,使用瀏覽器本身處理javascript的速度,以及記憶體,已經是一種很確實的趨勢。


當然地相對也有缺點,因為實際上瀏覽器只有做過一次前景的HTTP GET,剩下的都在背景執行。如果你有頁面本文想讓搜尋引擎的BOT去取得,那是絕對無法取得的,也就是說搜尋引擎將無法搜尋到你的頁面。然而我想現在也會有些補救性的作法,例如事先將關鍵字放在meta或title裡,或者乾脆先將本文載入到一個隱藏的div裡也可以。然而Google也不是省油的燈,在這一篇「10個不應該使用動態檢視的理由,Google的回應」(http://www.mybloggertricks.com/2012/05/google-response-to-our-post-on-dynamic.html)中,確實有提到Google Crawler早就有支援Ajax,只是其他的搜尋引擎有支援嗎?這還得再看看了

綜合起來,透過一些商業Web服務逐漸都投向SPA的懷抱,HTML5,CSS3的興起,也證明瀏覽器的效率,功能都逐漸的在提升,競爭也算是激烈。然而該怎樣寫這樣的軟體?除了得改變過去的想法以外,也得藉助本文中提到的這些Web Framework。





你其實根本不需要Framework?


有些web app根本不需要什麼精巧快速的畫面,他們要的是「穩定」,「相容」,從這個角度乖乖地從server side送HTML還可以避免掉許多問題。這些並非純粹寫client side,反而仰賴server side rendering,畫面上的javascript頂多就是個做menu的工具,也是完全不需要Javascript with MVC的。


我相信對於許多達人級的javascript開發者,可能根本不屑用這些東西,也或許他們自己就有足夠撰寫framework的實力。很多所謂最新的framework都還在0.x版,新的又出,長期看下來確實有點不知所措。然而如果你是新手,光學HTML,CSS都頭昏腦脹,你又何以有時間在javascript大膽地套用MVC?不得不承認的一點,不管這些framework在怎樣變化,在怎樣封裝程式碼,如果不熟悉javascript的話那可是玩不下去的。


所以就現在的角度看來,你會需要用到這些framework大致上可能有著以下理由:
  • 你的web app需要非常順暢的操作及效果,你想要藉此讓使用者大吃一驚。
  • 你的server side主要是提供資料,也可能被設計成只能提供資料。有可能資料存取的模式只有唯讀(HTTP GET),也有可能是RESTful。資料的格式則多半是JSON。你會想要這樣子的理由也絕大多數是為了節省server side的CPU時間。
  • 你的UI早期本來就是透過許多複雜的javascript構成,你既沒有使用YUI或EXT-JS(Sencha)來將你的UI使用多數的元件來構成,而即便你有,也是將自己的程式碼與元件混合撰寫。長久下來畫面累積一多,你已經發現難以維護,也難以交付給任何接替者。


也因此,在你學習使用某些web framework的時候,幾乎可能也得思考你的app是不是接近SPA?你需要的是widget型,還是輕量型,還是混合型?

Single Page Application撰寫時不得不該注意的幾點


HTML DOM Element並不是單純的tag,也並非是只是拿來描述layout,他是元件的堆疊
DOM Element在瀏覽器的記憶體內會形成一種結構,而結構會形成你的畫面。相對於在早期撰寫Ajax來使用server side rendering來更新部分畫面,現在是即時地更新一組「畫面上的元件」。所有你在撰寫SPA的時候會做的事情就是「操縱一組DOM Element」。




畫面並非平面的概念,而是具有層次的
以往div還有人在使用z-index來切換圖層。然而透過jquery,這些僅僅只是show和hide的概念。你可以將畫面層疊,也可以切換,混合特效來做完美的銜接。 


善用Model Class來加速你的資料取得與減少程式碼
即便你不需要Controller與View的幫助,讓你想像伺服器端的資料只要透過幾行程式碼的定義,就可以「與瀏覽器同步」,那接下來不管怎樣也是一件輕鬆且令人開心的工作。也就是說,在client side model class就是server side model class的proxy。當然在這個情況之下,中間的資料傳輸可能就是透過RESTful API,或是單純的HTTP GET來取得JSON Data。最近有朋友討論到RESTful這個字眼,看起來這個字眼可能還是造成一些誤解所以在此說明。RESTful簡單來說指的就是利用HTTP GET/POST/PUT/DELETE來對某個URL所代表的資源進行CRUD的操作,而與這個資源用怎樣的資料格式傳送並沒有關係。但由於JSON總是比XML好用,也因此可能造成一些誤會,使用JSON進行HTTP GET就是RESTful。





符合需求,你需要更好的UI設計
所謂的直覺並非是你自己想的到或是老闆告訴你的直覺,想當然爾每個人的直覺都不同,每個人覺得簡單也都不同。直覺是你要熟知用的人是誰,去跟他們訪談,瞭解他們的習性,清楚他們的工作習性與目標,設計減少他們工作量的UI,這樣他們就會很喜歡,也會說你的UI很「直覺」。如果你是設計Web app的人,那更必須清楚大家怎樣用瀏覽器的。你真的確定寫Web app只是把一格一格的東西放入瀏覽器?沒有更好的作法了?





善用SPA本身的優勢,盡量不要重新讀取,也要善用快取
SPA的觀念就是將所有javascript程式碼載入到瀏覽器的記憶體,被瀏覽器解析後開始執行。多虧了現代瀏覽器善用bytecode來加速執行的好處,只要你的程式碼在伺服器端沒有更新,你根本可以將SPA視作就像Adobe Air一樣的平台,下載後就開始執行。由於是直接使用javascript,html及css,相對地很好做混搭(mashups)。既然是一次性地將程式碼載入並且執行,就必須使用javascript history來控制上一頁下一頁的動作,所謂的頁面切換也不過是DIV切換。所有靜態的資料,例如圖片,CSS等,應該優先載入。也必須檢查好web server有沒有設定好快取,即使是json資料,只要沒有更新的資料就不該重新讀取。接著就只要從server讀取json資料即可,這樣來讓瀏覽更加順暢。



Top 10 Javascript MVC Framework Reviewed


英文原文:The Top 10 Javascript MVC Framework Reviewed (http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/)
我認為這一篇已經寫得很精確了,以下我就做個翻譯,如果有額外的想法就用紅字。

2012/04/14更新:新增Batman.js及Angular.js,因為大家需要而且看起來滿不錯的。

話說之前幾個月我不斷地尋找優良的Javascript MVC framework,由於急需正確的抽象化階層以及功能,有些也是因為好奇,我就一個一個拿可以取得的framework來嘗試。以下就是各個framework的簡介,還有分享一下最後我決定使用的framework。

特別說一下這些是對我來說很重要的功能:

  • UI綁定:我並不是說在說畫面範本(templates),而是說在底層的model改變的時候自動更新顯示層元件的方法。一旦你嚐過這類型framework的好處(例如Flex),你就再也回不去了。
  • 可組合的顯示層:就像所有的開發者,我喜歡可重複使用的程式碼。所以說,在撰寫UI的時候,我喜歡可以組合的顯示層(最好是在範本層)。換句話說最好是顯示層元件有著豐富的元件層次可以使用。例如說就像是可重複使用的分頁元件。
  • 使用原生Web功能作為展示層:我們都是在寫有關web的東西,所以我最後想要的就是原生樣式的顯示元件(直接使用css及html來改變顯示樣式及layout,而非透過javascript)。沒道理讓web framework來建立自己的layout manager。HTML和CSS就是最好拿來改變樣式及layout的東西,也應該就是這樣用。最好整個framework的設計應該都要圍繞在這個觀念上。
  • 與jquery互相合作:老實說吧,jquery確實很讚。我不想要一個framework自己又寫了一個像是jquery的東西,我希望他就直接使用jquery。


競爭者

這個表就是所有支援上述功能與否的framework,向下捲來看詳細的解說。


FrameworkUI 綁定可組合的顯示層使用原生Web
功能作為展示層
與jquery互相合作
Backbone.js
SproutCore 1.x
Sammy.js
Spine.js
Cappuccino
Knockout.js
Javascript MVC
Google Web Toolkit
Google Closure
Ember.js
Angular.js
Batman.js


1. Backbone.js

Backbone.js是web的親密好友,你應該在各個地方都會聽到,而且有很多知名的網站也使用。基本上這就是我第一個嘗試的framework,我用這個做了一些Group Talent的後台管理功能。

優點:強大的社群和許多的互動,(他們所使用的)Underscore.js也是一個很好的framework。

缺點:缺少明確的抽象層,將一些東西留給開發者決定。整個framework嚇死人的輕量化,結果就是有些東西還得開發。你的應用程式寫越大,這個狀況就越明顯。

2. SproutCore 1.x
SproutCore是Apple用在他的iCloud上的,儘管名字看起來很詭異,不過整個framework都有很好的想法。這也是其中一個最大的framework。

優點:支援綁定,穩固的社群,數不盡的功能。

缺點:餅畫太大,很難與不需使用的功能分割。需要使用者接受仿HTML的開發模式,我對於這種不拿原生HTML當作layout的framework很頭大。

3. Sammy.js

我花了點時間在這個小framework Sammy.js上,因為他很簡單,差點讓我寫不出上面的表來。他的核心功能是個用來切換ajax應用程式的路徑系統。

優點:簡單的學習曲線,很容易的就可以與現行的server應用程式整合。

缺點:太簡單了,根本不適合來寫大軟體。

4. Spine.js

從名字來看,Spine.js顯然很受backbone影響。如同backbone,他很輕量,也遵循同樣的模式。

優點:輕量化,文件很齊全。

缺點:設計上有著根本的問題,spine的核心想法是「是個非同步的UI,簡單來說,UI理想上不應該block」。以前我曾經認真寫過即時的non-blocking應用程式,我可以說根本不太可能,除非後端使用的是Operational Transform機制。

5. Cappuccino

Cappuccino是一個獨特的framework,伴隨著而來是他自己的語言Objective-J。Cappuccino是想在瀏覽器上模擬cocoa。

優點:嚴謹考量的framework,良好的社群,很好的繼承模型。

缺點:思考過所有你可以用javascript模擬的語言,最不應該選的是Objective-C。這是一個ios的開發者搞出來的,我怎樣就是想不通為啥要在瀏覽器上用Objective-J來寫。

6. Knockout.js

Knockout.js是一個MVVM framework,並且受了不少支持者的讚美。他強調他有宣告式UI綁定與自動UI更新的功能。

優點:支援綁定,相當好的文件與教學系統。

缺點:糟糕的綁定語意,也缺乏顯示元件階層。我只不過是想要簡單地重複使用元件,然而我卻覺得將這個framework認定為MVVM好像不太對。其實這類型的framework不應該稱為MVC,而是MVx(MVP, MVVM ...等等)

7. JavascriptMVC

JavascriptMVC從所有顯示出來的狀況看來,是我沒打算花很多時間的framework。

優點:穩固的社群和傳統。

缺點:使用字串當作屬性,糟糕的繼承模型。Controller跟View太靠近,也沒有綁定機制。命名方法太單調,與其相對等的就是RoR,也可以說是Ruby派的Web framework。

8. Google Web Toolkit

GWT是一個嚴謹的client-side toolkit,包含的不僅僅只是framework。他將java編譯成javascript,也支援標準的java library。Google內部使用這個在Wave上。

優點:完整的framework,優良的社群。穩固的java元件繼承模型,適合超大型的client-side應用程式。

缺點:先別管Google怎樣說,GWT是無法經過時間的考驗。如同像是DART這樣的單位所說,很清楚的Java無法成為Web的未來,此外Java在client上面的抽象化其實爛透了。

9. Google Closure

Google Closure與其說是framework不如說像是toolkit,也附帶有編譯器及最佳化工具。

優點:Google在多數的的軟體上都有使用,良好的元件化UI系統。

缺點:沒有UI綁定


10. Ember.js

Ember.js(前SproutCore 2.0)是個最新的競爭者,他打算將核心功能從SproutCore 2.0移出,變成一個更小更模組化,更符合web的framework。

優點:極度豐富的範本系統,也包含可組合的顯示層級UI綁定。

缺點:因為很新,所以沒啥文件

11. Angular.js

當我在發這邊文章時,我發現了Angular.js這個不錯的framework。由Google開發者開發出來,裡面有些不錯的設計概念。

優點:對於template及controller有著不錯的整體想法與設計,有個Dependency injection系統(我可是IoC的大粉絲),支援豐富的UI綁定語法來讓過濾和數值轉換非常輕鬆。

缺點:程式碼看起來有點亂,不是很模組化。view還不夠模組化(在Batman.js裡會在多提到)

12. Batman.js

Batman.js是由Shopfly開發的,與Knockout及Angular同一派。使用了HTML的屬性,有個很好的UI綁定系統,是唯一個使用coffeescript編成的framework。他與Node.js高度整合,甚至可以使用自己的Node.js server。

優點:非常乾淨的程式碼,使用很好的方法來達成綁定,物件儲存(persistent),路徑選擇。

缺點:我非常不喜歡singleton,因為他導致了singleton controller這樣的想法。Knockout及Angular都因為這樣而在巢狀元件上有了同樣的毛病。我希望可以宣告式地使用多個範本,Ember比他們好的地方就在於可以宣告式地重複使用以他們的機制做出來的元件。

最後贏家


最後Ember.js是唯一個具備所有我想要功能的framework。我最近移植了一個使用backbone的小軟體到ember上,儘管效率上有點問題,我倒是覺得程式碼少了點還不錯。由Yehuda Katz所帶領的整個社群也非常不錯,這絕對是值得關注的framework。


當然這個表還不夠完整,這些framework幾乎都是因為臭名,口傳,或是Hacker News上所提到的。此外我也沒有看商業的framework(或是那些licence亂搞的...就是在說你啊ExtJS)。


那你現在正在用哪個framework呢?






結論

我確實有一陣子很喜歡用JavascriptMVC,不過我也確實在使用的過程中感到他真的是過度複雜。ROR模式很適合撰寫server side,然而client side呢?不管怎樣client side你也只有javascript可以用,翻譯過也才知道原來除了java to javascript,還有object-j to javascript。不過這些不管怎樣說都只是一些變形,連作者都說有些甚至不太像MVC framework。

以Ember.js的作法相對於SproutCore及JavascriptMVC看起來,確實一直不斷地堆積功能是沒有用的,果真還是得瞭解MVC在javascript上如何運用,如何使用原生的HTML及CSS功能,來減少不斷重新開發輪子的痛苦。


8 則留言 :

  1. I like your post very much. It is very much useful for my research. I hope you to share more info about this. Keep posting angular js course

    回覆刪除