Single Page Application - 下一代的Web應用程序

在Web Service, Ajax, Web 2.0,REST等Web應用與技術話題熱潮,帶動許多第二代的Web開發技術成長以後,這些話題也漸漸地消退。不過許多人可能未曾發現,其實這些技術名詞,是在慢慢地顯露一點:Web應用程序逐漸從ServerSide轉移到Client Side,也就是瀏覽器身上。 javascript

本篇文章要從以往的Server Side Web應用程序,其開發方式與演進來介紹Single PageApplication(SPA) 與現今全部主流Web技術。 php

我在Web2.0過去,如今與將來介紹Ruby OnRails都有提到一些Web技術的演進,比較明顯的趨勢就是從靜態到動態頁面,而設計的方式也更程序化。而在http://atedev.wordpress.com/2007/01/09/Web2.0:過去,如今及將來/也有讀者在前言提到,技術並非將一個名詞安上去就好。我至關贊同這句話,所以也在這篇文章中但願來作個總整理,以技術及歷史來看看Web是怎樣成長的。 html

Web應用程序的演進 java

動態網頁 web

Rich Internet Application 數據庫

Single Page Application json

定義 後端

所依賴的Web技術 數組

SPA的架構 瀏覽器

Rails與SPA

結論

Web應用程序的演進

動態網頁

儘管Web並非一個三言兩語能拿個版本號碼來解釋,但實際上Web技術確實有些明顯的分隔點。

最先期咱們熟知的就是靜態網頁,這應該沒啥問題。儘管在2000前,php,asp就開始流行,坊間的書上也都稱之爲動態網頁。而我在此說起的動態網頁程序,實際上倒是從php4釋出的那一年開始。這邊要讓你們瞭解的分界點,實際上是php4開始被許多商業公司所採用,而軟件的形式也更爲套裝化,而再也不像以前你們認定的「動態」網頁僅僅只是拿來完成一些簡單的區塊來與通常的靜態網頁整合。

在2004年的時候,WebFramework的產生,創造了Web應用程序另外一個新的高峯。而在這個時候也開始有一些Rich WebClient概念的雛形了。我將Ruby OnRails定爲一個分界點是由於,他顛覆了傳統動態網頁還在使用設計方式,而改用MVC。但要注意的是Ruby OnRails儘管整合了Ajax與進階Javascript函式庫,但仍是沒有改變回傳完整或部分HTML的方式,意思即是HTML的產生始終在ServerSide。

Rich Internet Application

一直到如今,有至關多的Web應用程序,都仍是維持使用URL來切換各類功能與畫面。而這些以「頁面」爲主的程序,並不太須要控制DOM,就不常遇到跨瀏覽器問題。然而自從Firefox逐漸也在市場佔有一席之地,Javascript的應用普及以後,跨瀏覽器問題也接着發生。爲了避開各類不一樣的瀏覽器所帶來的問題,各大企業都獨力發展本身能夠嵌入在瀏覽器的應用程序。早期如JavaApplet及微軟的的Active X,算是Rich InternetApplication(RIA)的開始,但效能方面仍是差強人意。

直到2004年的時候,RIA出現了兩種不一樣的實作方法:一種是承襲以往須要安裝額外Runtime或是在特定瀏覽器才能執行的方式,稱作Sandbox;另外一種是隻採用CSS,HTML,並以Javascript控制HTMLDOM的Dynamic HTML方式,優勢就是隻須要瀏覽器就能夠執行。然後者也延伸出利用OfflineDatabase或是Ajax+WebService來傳送與儲存程序數據,並能夠儲存成一個獨立頁面的Web應用程序,稱作Single PageApplication(SPA)。SPA最典型的例子,就是Gmail。Google盡力克服了跨瀏覽器的問題,將Javascript發揮的淋漓盡致,讓你們驚歎光靠純粹的Web技術竟能作到如此程度。

而我將2005定爲SandboxRIA真正開始的年代,也是由於Adobe併購Macromedia,而有了較完整的開發環境與資源,並非以往單純地嵌入Flash。這個契機也促使微軟改變策略,比起效能較差的Asp.Net,而拿Sliverlight做爲Web下一代主力軍。

RIA或SPA都是學習歷程長,語言多又複雜的Web應用程序技術,也所以發展速度至關緩慢,但不可小看的是這些優勢:

·        相較以往在Server上產生HTML並回傳至瀏覽器,任何畫面皆利用瀏覽器自己或附加的功能來產生。形同於借用了Client SideCPU的運算資源,減小Server成本。用戶感覺到的互動性與響應速度皆有大幅的提高。

·        因爲Server並非每次都回傳複雜龐大的HTML,而是利用XML或JSON傳輸數據的部分,使用的帶寬也相對變小。

·        Server Side除了使用傳統XML WebService,更能夠採用REST,讓Client的應用程序能夠更快速掌握數據的新增修改刪除(CRUD)並簡化呼叫的服務URL。

·        可以快速Mashup其餘的Web應用程序資源,又能擁有高速的執行效能。

下表列出了Web技術的演進,要注意到後三種技術集合,其時間是並行的:

 

靜態網頁

動態網頁程序

Web應用程序

Rich Internet Application with Sandbox

Single Page Application

時期

2000之前

2000(php4釋出)~2004

2004(Ruby On Rails釋出)之後

2005(macromedia被adobe併購)之後

2004(Gmail釋出beta)之後

表現層

CSS

CSS,HTML,Javascript

CSS,HTML,Javascript

Flash, Sliverlight

CSS,HTML(DOM)

邏輯層

Javascript

Template或自行撰寫

Web Framework

Action Script, C#

Javascript或是撰寫Web Service的語言

資料層

HTML

Database(SQL)

Database(ORM)

Database(ORM)

Offline Database, Web Service

開發方式

網頁編輯程序

整合HTML及Server Side語言的編輯器

整合Web Framework的IDE

整合Sandbox的IDE

整合Server Side與Client Side語言的IDE

運算資源

全部數據直接透過Web Server送出,除了硬盤讀取,幾乎不須要額外的運算

由於使用了Server Side語言來Render表現層,運算多半會消耗在Server

由於使用了Server Side語言來Render表現層,運算多半會消耗在Server

運算資源平均被分散在Server及Client,但Client須要Sandbox去執行,因此會消耗更多CPU資源

運算資源平均被分散在Server及Client

數據格式

傳送完整的HTML

傳送完整的HTML

傳送部分或完整的HTML

只需第一次傳送HTML及內嵌程序(Flash或Sliverlight),其他傳送XML

只需第一次傳送HTML及Javascript,其他可傳送XML或JSON

優勢

簡單易學

學習同一種Server Side語言,搭配簡單的HTML,CSS,JS觀念便可以有成果

整合Ajax或進階Javascript函式庫,REST及MVC。使得設計概念更爲面向對象化

用戶接口反應快速,變化多且美觀。兼顧窗口程序的反應速度,且能部分兼容傳統HTML應用。

徹底兼容傳統HTML應用,及任何可能的Web應用程序Mashup。能夠採用不一樣的傳輸方式,並和REST及瀏覽器快取來節省帶寬,使得總體反應至關快速。

缺點

沒法讓用戶儲存任何應用程序數據,任何數據必須藉由人工設計

對於龐大的應用程序,便得花上大量的Server成本。程序反應速度受限於服務器負載,須要叢集架構來彌補。

設計方式更爲簡單快速,但相對於傳統的動態網頁程序付出更大的Server成本。

除了CSS,HTML,JS之外還需學習一兩種不一樣的語言才能進行開發。RIA一般程序數據較大,在開始使用前必須等候一段下載時間。

除了CSS,HTML,JS之外還需學習一種撰寫WebService的語言。須要至關熟悉DOM及CSS,也需考慮瀏覽器的差別,開發起來相對地困難許多。

表現層的演進能夠得知,無論是RIA利用sandbox或者是SPA利用DHTML做爲表現層,相較起來傳統以文字HTML拼湊出畫面的做法已經沒法符合使用者的需求。更動態,更彈性的做法才能讓使用者得到操做感。

而在邏輯層上,演進到了SPA則是變得較爲複雜。若是是使用Web Service做爲ServerSide,除了必須撰寫該語言外,也仍是得撰寫Javascript來控制畫面的呈現。而這也影響到開發方式,以往的編輯器多半着重一種主要的語言上,但如今的WebIDE多半均可以完整的處理全部瀏覽器的語言,及多種Server Side語言。例如Aptana IDE就是最好的例子。

數據層的演進就比較簡單,直到RIA的時期,仍是至關依賴傳統的Database。但SPA的時期,就能夠採用OfflineDatabase,這裏指的就是Google Gears。但若是要使用傳統的OnlineDatabase,所有都還沒有有Javascript的Client,就必須透過WebService來轉換數據。而在SQL到ORM的演進上,雖然使用面向對象的做法減緩執行速度,但相對下降開發難度,帶來更大的價值。

Single Page Application

定義

請參考 http://www.answers.com/topic/single-page-application?cat=technology 

Single Page Application是一種WebApplication,徹底地在瀏覽器上執行。也就是說,標準的SPA程序是不須要網絡聯機的。

像這些範例,你可使用firebug來觀察聯機的動做。

·        TiddlyWiki http://www.tiddlywiki.com/:這個wikieditor,除了整整一萬行的javascript之外,只有一個很簡單的起始頁。就算你拔了網絡線,也只是不可以儲存而已。但他要如何儲存編輯好的wiki內容呢?必須設定外部服務器進行同步做業。

·        Protopage http://www.protopage.com/:外型設計得很漂亮,操做感也很順暢。仔細觀察你也會發如今進行網絡傳輸的時候都是傳遞JSON。

而畢竟沒有網絡聯機的程序很難做爲應用,因此我在SPA架構一節會提出兩種SPA程序的演進。
在此也必須提出一個概念,SPA並不是只是一個「不切換頁面」或是「URL不變」的程序。而SPA所使用的觀念,就如同前言,已是將瀏覽器看成client端了。
既然是client端,那勢必表明中間是必須傳輸數據,而並不是HTML;也所以HTML的產生也會發生在client端,而並不是傳統由server產生HTML再由瀏覽器加載。

所依賴的Web技術

AjaxAsynchorous Javascript AndXML,早期Ajax被用做來傳輸單純的HTML或是XML,而且利用DOM的innerHTML屬性來更新部分HTML內容。現在Ajax在SPA中被看成重要的傳輸媒介(Transport),不管模板數據到應用程序數據,都是利用Ajax在背景傳輸完後,再由JavascriptTemplate來產生HTML。

JSONJavascript Simple ObjectNotation,在標準的Javascript語法中,以{ }及[]這兩個語法,能夠宣告對象與數組,並可使用eval函式將他轉換爲Javascript對象。例如object=eval_r(」({a:’b'})」),此時object對象便有一個屬性」a」其值爲」b」。在SPA中,JSON被運用來做爲一種數據格式,藉此取代複雜的XML,以節省帶寬。而傳輸的JSON數據又能夠快速還原爲javascrip對象,又更節省程序執行的時間。

在SPA中,HTMLDOM是一個最重要的元素,尤爲是DIV及SPAN等Container的操做更是。因爲絕大多數的畫面都不進行任何換頁的動做,程序裏大部分都是在控制DOM及Container。而對於A(Anchor)而言,href裏的URL也沒有太大意義,多半都是在onclick裏寫javascript,或是用Javascript函式庫去bindonclick事件。因爲直接呼叫瀏覽器提供的DOM函式庫功能,會遇到像IE同樣不符合W3C規格的問題。要選用一個合適的Javascript擴充函式庫,如Prototype.js或是jQuery,如此纔不會有太多跨瀏覽器問題。

CSS在以往的Web應用程序中,多半都拿來看成畫面的修飾,佈景主題或是顏色特校。但在SPA中,必需要熟悉CSS的Dimentation(長寬控制),Classification(顯示行爲),Positioning(定位)。在沒法換頁的情況下,只能靠着移動,隱藏,顯示這些方法來控制畫面的元素。若是要了解這些進階CSS的主題,均可以在w3school裏的教學找到。

Trimpath是Google爲了SPA而開發出來的一個函式庫集合,也能夠說是Rails的Javascript版。若是要撰寫上述第一種SPA,就必須利用到Trimpath的所有,而第二種只須要用到TrimpathJavascript Template便可。JavascriptTemplate(JST)如同PHP的Smarty同樣,是標準的模板技術,只是採用的語言是Javascript。爲了撰寫SPA,必需要好好地運用JST。

快取的機制在SPA也至關的重要,爲了達到讓用戶感覺到程序的反應快速,就必須應用多方面的快取。

·        ViewCache:SPA中的View就是指已經顯示出來的HTML,不少經常使用,而不須要常常改變的HTML,就能夠將放在Container(DIV或SPAN)裏。不用的時候就隱藏,須要的時候就顯示。而另外一種方式是能夠用z-index將選單或是清單的Container放在最下層,而要回到這個清單的時候就將蓋在其上的container隱藏。

·        Template Cache:通常來講JST的模板數據只要讀取一次就能夠,又由於這些只是字符串,能夠直接就存在Hash裏。

·        JavascriptCache:在我提出的SPA實作中,有一個特性是將各個JST的「行爲」程序代碼分開,就如同sap.net將aspx與cs檔分開的做法同樣。而若是採用這個做法,不須要重複讀取的javascript就必需要快取。

·        DataCache:資料快取是最難的一部份,牽扯到了緩存一致性的問題。而如今在javascript中並無對於XML或JSON的數據快取解決方案,將來若是可以有這樣的函式庫,就可以更提高總體的效率。

以上說明的都是Client Side所必需要使用到的技術,而ServerSide的技術多半與Service Design息息相關。

RESTRepresentational StateTransfer,他比較像是一種設計樣式(DesignPattern),而不是Web技術。在以往Web應用程序的規劃中,URL並不徹底具備意義,傳輸的內容型態多半是HTML,而HTTP的各類動做也並未徹底利用。在SPA中,因爲須要在不一樣時間傳輸各類數據,如HTML模板,JS模板,或是XML及JSON數據。此時REST的設計技巧就能夠節省下不少重複的命名,而讓程序代碼總體更有意義。支持REST設計樣式的Web Framework如Ruby OnRails,讓總體設計較爲簡單。

SPA的架構

SPA就分類而言,算是RIA的一種,只是不採用任何的sandbox而已。典型的SPA是不須要任何的後端的WebService或是Offline Database,只須要一個htm檔或是一個網頁就可以運做,如微軟的HyperTextApplication(HTA)就是,但仍是缺少完善的數據儲存能力。

第一種SPA程序,如同著名的GoogleReader脫機版,具備一個脫機數據庫與一個同步管理程序,在有網絡聯機的時候,會將數據同步回在線的數據庫。這個最大的優勢就是徹底利用了Client的CPU資源,使用者雖然看見的是網頁,但倒是在使用在本機執行的獨立應用程序,所以速度是至關流暢。比起通常的動態網頁,這樣子的使用體驗更可以顛覆通常人對於「網頁」的見解,而逐漸瞭解何謂Web應用程序。另外一個例子是使用Trimpath函式庫撰寫成的NextAction,是一個多功能的ToDoList。

另外一種就是較簡單的SPA,不具備脫機瀏覽的能力,可是承襲了使用javascript的高效能。必須說起的是ServerSide並非採用XML,而是能夠快速轉換爲Javascript對象的JSON,來看成Web Service。如此ServerSide的語言只須要具有可以快速將對象serialize成JSON的能力便可。

Rails與SPA

這個小節所要說明的是至關技術性的部分,沒法說明的太詳細,有興趣的讀者能夠寫mail一塊兒討論。爲了簡化觀念,我使用SequenceDiagram來講明Rails要如何應用在SPA上:

·        URLRequester是一個javascript函式,主要的工做就是以REST方式對一個URL進行不一樣Content-Type的Request,而且將回傳的資料產生HTML,並填到container裏顯示出來。

·        HTTPRequest在這裏做爲進行Ajax呼叫的傳輸媒介。

·        RailsController表示服務器端對應至特定URL的程序,在這裏也必須使用REST方式來響應。也所以若是要求content-type爲HTML的時候就傳JST模板,要求JSON的時候就傳數據,要求javascript的時候就傳javascript文件。

·        RailsModel表明服務器端的數據庫,在要求數據的時候,勢一定要連數據庫來取得數據的。而回傳的時候,就將ruby對象serialize成JSON。

1.    Client呼叫URLRequester函式,例如http://servername/controller/action/id。

2.    HTTPRequest送出一個要求,並指定Content-Type爲HTML。

3.    RailsController接到指定的URL,並執行controller#action。我將JST寫在rhtml裏面,JST基本上也是html,不過是模板的卷標換成{}而已。由於REST設計方式會由於指定的content-type回傳對應的型態,此時直接將內容的JST文件傳回。

4.    在前面我有說起快取的重要性,因此這裏就快取住這個JST,下次要求一樣的內容就能夠直接使用而不用重複傳輸。

5.    對於同一個URL,使用HTTPRequest送出要求,並指定Content-Type爲JSON。

6.    由於REST的特性,此次會執行到content-type爲JSON時的程序代碼,接着就能夠照通常方式使用RailsModel讀取數據庫。

7.    Model傳回的Ruby對象,固然就要轉換成JSON回傳。而在ruby中至關簡單地即是呼叫to_json就能夠轉換了。

8.    回傳的JSON,並和剛剛快取的JST,使用trimpath javascripttemplate函式庫產生成HTML,並更新至container裏。

9.    在這裏我採用行爲javascript程序代碼與範本分離的方式,因此仍是以HTTPRequest再次傳送要求,並將Content-Type指定爲Javascript。

10.  一樣地根據要求的content-type,會回傳javascript文件。

11.  快取,並呼叫eval執行回傳的javascript。

12.  將container顯示在想要放置的畫面區域。

結論

許多人都在說Web2.0可能又是另外一次的泡沫化,這個熱潮怎樣開始的,又怎樣消退的,也是至關明顯。網絡上對於各類新技術名詞的炒做,將不一樣應用層次的技術,所有攪和在一塊兒說明或稱作是最終解決方案,也模糊了使用者的眼睛。那麼,在這個時代,到底還有什麼能夠相信,能夠學習的?

惟一可以作的就是從新審視這些技術,瞭解因果。就能夠知道哪些做法是適合用在本身如今的項目,那些是本質相同的,哪些是跨大其詞的。根本的觀念正確,就不須要擔憂這些延伸的技術是否會有誤解或誤用。

相關文章
相關標籤/搜索