本篇介紹如何藉由改善 ViewState 所造成網路傳輸的負擔,來提高 ASP.NET 的傳輸效率。
ViewState 其實說穿了,就是以前在JSP、ASP、PHP常用的 input tag 而它的型態是 "hidden", 用來記錄一些網頁狀態之用,如下所示:
<input type="hidden" name="__VIEWSTATE" value="...." />
而 ASP.NET 更將它發揮至極致,他用 ViewState 來儲存 Page 所有元件中各項屬性的狀態, 例如 TextBox 的字型、大小等等,而這一切接由 ASP.NET 的內部機制自動完成,我們只要 使用就好了,不需去考慮其中複雜的流程。
當然,要享受它的優點同時也就要接受它的缺點,而我們可以藉由 Control.EnableViewState 這個屬性來做一選擇,這單看你的系統內容而定。
本篇文章,就是根據這一問題作一探討,看有沒有一兩全其美的方式。
目標閱讀者:
對 ASP.NET 的 ViewState 流程有一定的瞭解。
簡單來說 ViewState 的原理,就像你要使用一個變數一般,首先就是要先設定變數, 再把變數拿出去使用,ViewState 也是一樣,首先要先 Save ViewState 來設定 ViewState 的值, 再由 Load ViewState 來取得 ViewState 的值。
在 ASP.NET 中,每個 Control 都會有其相對應這兩個動作的函式,而 Page 就是大總管, 由 Page 來呼叫每一個 Control 相對應的函式,這個並不是本文探討範圍,有興趣的讀者 可去參考“深入剖析 ASP.NET 元件設計”一書,我看了一下裡面寫的還蠻詳細的。
而在 Page 中相對應做這兩個動作的就是 SavePageStateToPersistenceMedium 和 LoadPageStateFromPersistenceMedium 這兩個函數,所以在這隻要覆寫這兩個函數,把 ViewState 的值 save 至另外的儲存體, 在 Load ViewSate 時再從你的儲存體中,還原這個值即可,程式碼如下所示:
protected override void SavePageStateToPersistenceMedium(object viewState)
{
Session["VS"] = viewState;
}
protected override object LoadPageStateFromPersistenceMedium()
{
return Session["VS"];
}
我建了一千筆的資料,使用 DataGrid 來顯示所有欄位,畫面如下所示,在未使用上述方法時,總原始碼的大小為 471 KB,使用後減為 202 KB,足足 少了一半有餘,由此可知該方法對於傳輸效率的改進,當然,此先決條件是你 元件的資料量很大的時候,才會有顯著的改進,但有上述程式碼可知,本方法 不是很難的作法,如此即可在很低的改進成本下獲得不錯的效果,所以還是很 值得一試的。
該方法對於傳輸效率的改進,當然,此先決條件是你 元件的資料量很大的時候,才會有顯著的改進,但有上述程式碼可知,本方法 不是很難的作法,如此即可在很低的改進成本下獲得不錯的效果,所以還是很 值得一試的。
以上說明,可知本方法是使用空間換取時間的作法,如果貴單位伺服器記憶體 不足的情況下,亦可將 ViewState 的值存在實體空間中(如硬碟),如何才是 最好的作法,並無一定定論,要視系統內容、使用者使用習慣而定。