加入RUN!PC粉絲團
最近新增的精選文章
 
最多人點閱的精選文章
 
 
精選文章 - 開發技術
分享到Plurk
分享到FaceBook
 
Pure AJAX之道(上)
ASP.NET AJAX Templates初探
文/圖 李明儒.責任編輯/洪羿漣

隨著Web介面對親和力、操作流暢度的要求日益提高,採用AJAX技術改善網頁操作靈活性已成為當今網站設計的必備要求。ASP.NET 2.0 UpdatePanel神奇地實現了開發者不需JavaScript便可達到酷炫的AJAX動態更新效果,但在ASP.NET AJAX 4.0中,將會有另一波革命。

從最早只為了整合文字與圖片的HTML網頁出發,演進至今,網站應用與網頁技術已與最初截然不同。檢視歷來微軟發展的各項網頁技術,可以看出有趣的演進變化。

最早期的FrontPage是以HTML編輯為主,FrontPage Server Extension以類似CGI的概念提供一些便利應用。當時網頁互動應用需另外撰寫CGI程式承接HTTP POST送回的結果加以解析處理,結果再以HTML格式傳回,開發不易,加上每個Request都由獨立Process處理,效率並不好。

ASP同時參雜HTML Tag與Server-Side Code的做法,相較於CGI操作介面與邏輯的分散,操作介面與邏輯被放在同一檔案,編輯維護上簡便許多,而執行模式也改由ISAPI包辦,效率明顯提升。但ASP也有些缺點:當程式與HTML Tag過度穿插交錯時會導致閱讀不易;而開發者也必須清楚,哪些邏輯必須在前端寫、哪些則得在後端完成,初學者常因為觀念不清,加上Client-Side與Server-Side都用VBScript,老為了要不要runat=”server”百思不得其解,或是把Server-Side才能做的工作錯移至Client-Side處理。

ASP.NET推出後,一方面透過Code-Behind的方式讓Client-Site與Server-Site的程式碼完全分割,另一方面透過WebControl神奇地解決初學者不知道邏輯擺那裡的問題。透過ViewState及AutoPostBack屬性設計,原本在Client-Side要處理的邏輯(例如:下拉選單點選不同項目、文字輸入方格內容變動後的動態更新),都可以在Server-Side的事件裡完成,程式開發者只要會VB.NET或C#,就可以寫出完整的網站功能。

WebControl將Client-Side邏輯搬到Server-Side Event處理的做法的確讓開發流程單純化,也降低了開發者必須多學Client-Side Javascript技術的門檻,但不斷AutoPostBack的代價是--即便使用者進行的只是微小的操作(例如:勾選一個Checkbox),都會觸發一次全網頁資料POST回伺服器,再傳回HTML全網頁重新顯示的閃動,引發操作者反感。

當大量使用AJAX技術的網站問市,其操作過程「看不到任何網頁閃動」的流暢,與開發省事卻時時在PostBack閃動的純WebControl ASPX,形成強烈的對比,立即擄獲使用者的心,網頁AJAX化也頓成顯學。

要將原本WebControl型ASPX改造成AJAX風格,需熟知HTML DOM、HttpRequest Object、Javascript,對許多只會VB.NET/C#的開發者來說,是條艱辛漫長的路。微軟實在太為初階開發者著想了,在ASP.NET 2.0裡,神奇的技術又出現了:UpdatePanel。

只要在頁面上建立UpdatePanel,將原本的WebControl拖進UpdatePanel中,舞照跳、馬照跑,所有程式邏輯還是全部寫在Serer Side,一行Javascript都沒學過,照樣寫得出又酷又炫的AJAX動態更新。自此,ASP.NET初學者也可以四處炫耀,AJAX有什麼了不起,我也辦得到!(而且完全不用”J”)


UpdatePanel有什麼問題?
UpdatePanel的誕生,戲劇性地改變必須懂Javascript、HTML DOM才能寫AJAX的現實。但如同當年的WebControl,這些便利是要付出代價的。

UpdatePanel架構簡單、邏輯集中(不需另外寫Web Page/Service供前端呼叫)、開發簡便快速,加上完全用Server-Side事件解決,只要會寫ASP.NET的開發者就能上手,又不易出錯,門檻頗低(依筆者個人經驗,不會寫Javascript的ASP.NET開發者比比皆是!)。但是,UpdatePanel並非只有光明面,當然有其罩門:「效率!」

UpdatePanel背後的原理,是用HttpRequest的方式執行PostBack,肥大的ViewState要照送,完整的Page處理流程也要全程跑完,差別是網頁只是會產生UpdatePanel裡面的HTML Code傳回。換句話說,你要是整頁包在一個超大的UpdatePanel裡,傳的資料量就跟PostBack整個網頁相去不遠,因此要把握「UpdatePanel像比基尼,愈小愈好」的原則。

用個範例來檢視一下UpdatePanel背後沈重的傳輸真相。我們設計一個測試網頁,放一個Button1用來更新Label1的顯示時間,利用SqlDataSource將AdventureWorks資料庫的產品資料傳給GridView1並支援分頁顯示,當選取某項產品時,利用DetailsView1顯示產品明細,並展示產品照片。只需拖拉設定,這樣的網頁不用5分鐘就可以寫完。(圖1)


圖1:WebControl式ASPX。


大部分的東西都用宣告做掉了,我們只須處理按鈕更新時間及GridView1與DetailView1間的Master-Detail連動,要寫的Code不多,如程式1。


程式1


實際跑一下,分別按下Button1、GridView1翻到第2頁,並選取其中一個物項目。用HttpWatch Pro軟體觀察,可以看到4次傳輸,下載資料量都是7KB近8KB,第二次之後為PostBack,上傳資料傳輸量近3KB,主要因傳送ViewState的緣故。(圖2)


圖2:觀察WebControl ASPX操作時的網路傳輸。


完成了傳統網頁,讓我們加上UpdatePanel,讓它當場AJAX化!用一個UpdatePanel將Button1、Label1、GridView1、DetailsView1通通包起來(如圖3),Server-Side的Code一行都不用改,馬上升級成AJAX動態更新,網頁閃動Bye-Bye,改寫過程之簡單,直逼魔法。


圖3:使用UpdatePanel包入動態更新內容。


再觀察一下資料傳輸量,我們一樣看載入、按Button1、換頁、看產品詳情4次傳輸,結果如圖4。


圖4:使用UpdatePanel後的網路傳輸。


首次載入時,網頁HTML約9KB,並額外下載了三個js約90KB,但js部分未來可由Cache取得,不會每次重傳。但接下來的按Button1、換頁及檢視產品過程,雖然網頁不再閃動,傳輸資料量為上傳2.4KB,下載7KB,跟PostBack十分相近。也就是說,雖然換上了AJAX的皮,骨子裡跟PostBack造成的網路及伺服器負擔是差不多的。

依先前提過的「UpdatePanel比基尼理論」,現在我們就來把這件連身衣改成三點式!分別用一個UpdatePanel包住Button1及Label1,一個UpdatePane包住GridView1,一個UpdatePanel包住DetailsView1,並將三個UpdatePanel.UpdateMode改為Conditional,分別由Button1.Click、GridView1.PageIndexChanged、GridView1.SelectedIndexChanged事件觸發。(圖5)


圖5:使用三個獨立UpdatePanel。


拆成獨立UpdatePanel,讓我們可以每次更新一小塊,由測試結果來看(如圖6),資料傳輸量確有下降,但每個動作上傳的2.5KB省不了,按Button1、換頁、檢視產品分別產生了2.5KB、5.8KB、3.4KB的資料下載量。最過分的是單單更新Label1.Text幾個字元也要傳回2.5KB,其中超過95%來自傳回的ViewState。


圖6:獨立UpdatePanel版的網路傳輸。


由以上實驗來看,拆解出小而獨立的多個UpdatePanel,雖可以減少部分資料下載量,但每次更新,上傳跟下傳的ViewState終究還是省不了。在上面的例子裡,即便UpdatePanel內空空如也,去2.5KB、回來2.5KB也得行禮如儀。同時,UpdatePanel架構採行了全頁重新執行的概念,因此即便拆成多個UpdatePanel,同一時間內只允許一個UpdatePanel進行更新。

可以想見,若這樣的網頁要放在Internet上給成千上萬的使用者點閱,每次更新幾個字元就要來回5KB的資料量,頻率一高,對於頻寬將是沈重的負擔,何況處理這麼大量的資料來回,整條傳輸線路上的裝置都要耗費無謂的CPU、Memory、I/O資源,用嚴格一點的角度來看,亦不符合節能減碳的環保理念。在這類情境下,為求開發過程簡便快速、開發者多學Javascript太過勞累等,就不再是重要的考量因素,如何用最少的資料傳輸量達成同樣效果才是王道!於是,像ASP.NET AJAX Templates這種主打輕巧的設計概念便應運而生。


ASP.NET AJAX Templates
在ASP.NET 4.0中,為了克服前述UpdatePanel機制效能不足,提出了Pure AJAX概念,也就是希望回歸AJAX的精神,以Javascript為核心,讓瀏覽器與伺服器間的傳輸內容回歸到單純的資料本體,甚至以往透過XML格式包裝資料的做法,也主張改用更輕巧且更易在Javascript中操作運用的JSON(JavaScript Object Notation)格式。

在邁向Pure AJAX的同時,ASP.NET AJAX 4.0並不希望讓開發者陷入自己用Javascript解讀傳回結果,再將結果轉換成HTML DOM元素的忙亂。於是ASP.NET AJAX Templates出現,目標即在只寫很少Javascript甚至不寫Javascript的前題下,完成由後端取回資料轉成HTML元素的工作。

簡單來說,ASP.NET AJAX Tempates是一套Javascript Library,把大家已經很熟悉的Web Control Template概念移至Client端。程式2的語法對寫過一陣子程式的ASP.NET開發者應該不陌生。


程式2


在ASPX中穿插<%# ... %>就可以將動態內容注入到要顯示的結果中,十分直覺易寫。ASP.NET AJAX Templates的概念也大致相同,只是語法由<%# … %>換成{{ … }}。先不要扯到太複雜的前後端結合,用一個簡單例子做個說明,如程式3。


程式3


程式3有幾個重點:
1. MicrosoftAjaxTemplates.debug.js可由ASP.NET AJAX 4.0 Preview 3(http://tinyurl.com/5t36bn)取得,debug.js是易讀的原始碼版本,方便學習及偵錯,js則是可用於正式環境的壓縮版,能大幅減少下載傳輸量。
2. 範例中引用了微軟新納入的生力軍—jQuery。在jQuery的網頁初始函數$(function())中$create(Sys.UI.DataView)建立將Table的tbody部分設定成DataView。jquery-1.2.6.js可至http://docs.jquery.com/Downloading_jQuery 下載取得,使用Visual Studio 2008的人還可以得到額外的Javascript Intellisense支援,詳情可參考http://tinyurl.com/64dk4x。
3. var people = [ { }, { } ]是Javascript的簡要寫法,目的要建出一個由Object組成的Array當成Data Source。在實際運用上,當然不會是用Javascript 以程式碼手工打造資料物件,資料源多半會由WCF、Web Service或ADO.NET Data Service以JSON方式傳過來。
4. 一開始先設定tbody CSS類別為sys-template(重點在display:none),等set_data(相當於Server-Side的DataBind())後會將名為sys-template的CSS設定移去,元素就會顯現出來。
5. Bind資料的語法是{{ object_property_name }}。
6. Score.format("N2"), RecTime.format("yyyy/MM/dd HH:mm:ss"), Date.parseInvariant("2008-11-05 12:00:50","yyyy-MM-dd HH:mm:ss") 等方便的格式化功能是ASP.NET AJAX Data Type Extension附加的,只要在網頁加入ScriptManager後就可以呼叫,值得善用。

執行網頁,我們得到如圖7的結果,看來只是很簡單的HTML,但背後已是採用AJAX Templates所產生的。


圖7:AJAX Templates簡單範例的執行結果。



結語
在本期文章中,我們觀察到UpdatePanel資料傳輸量過大的缺點,並用Javascript Object Array當作資料來源,初步體驗了ASP.NET 4.0所提出的AJAX Templates技術。在下期文章中,我們將向UpdatePanel的例子看齊,繼續延伸實作出以WCF提供資料並支援Master-Detail顯示的整合應用,並比較Pure AJAX版與UpdatePanel的資料傳輸差異。



【原文刊載於RUN!PC雜誌:2008年1月號】