用 ASP.NET 2.0 改進的 ViewState 加快網站速度

來源:互聯網
上載者:User
asp.net|速度     如果您是個經驗豐富的 ASP.NET 開發人員,一提起 ViewState ,您可能會不寒而慄,因為您想到的是大量通過“雞尾酒吸管”吸入的 Base 64 編碼資料。除非採取步驟進行預防,否則大部分 ASP.NET 頁面將有大量輔助資料被儲存在一個名為 __VIEWSTATE 的隱藏欄位中,多數情況下,甚至不需要這個欄位。瀏覽用 ASP.NET 產生的您喜愛的網站,查看頁面原始碼,計算隱藏在 __VIEWSTATE 欄位中的字元數。我嘗試了一下,數量為 800 到 7,800 個字元。

  當然, ViewState 在 ASP.NET 中有個重要的角色。如果使用恰當,它能夠簡化頁面開發,改進使用者與網站的互動。如果置之不理,它能夠顯著增加網站響應大小,在連線速度慢的情況下,使您的回應時間更加緩慢。ASP.NET 2.0 的發布帶來了 ViewState 機制的一些改進,這使得 ViewState 使用更簡單,又不會防礙網站效能。這些改進包括:減少編碼數量,採用控制項狀態從內容中分離出行為狀態,以及智能整合資料繫結控制項。

  ViewState 基本原理

  在介紹 ASP.NET 2.0 ViewState 的改進之前,簡要總結目前版本中 ViewState 的用途和實現是適宜的。 ViewState 為 ASP.NET 開發人員解決了一個特定問題 — 保留伺服器端不形成元素的控制項的狀態。這很重要,因為 ASP.NET 中的大部分伺服器端控制項模型是根據這樣一個假設產生的,那就是 — 如果使用者回傳到相同頁面,所有控制項保持其狀態不變。也就是說,如果在處理請求期間修改任何控制項的內容,任何後續 POST 請求回到相同頁面時,您可以依賴於那些仍然存在的修改。作為一個活動的 ViewState 樣本,嘗試運行下面顯示的代碼。

<%@ Page Language="C#" %>
<script runat="server">
protected override void OnLoad(EventArgs e)
{
  int val = int.Parse(_sum.InnerText);
  _sum.InnerText = (val+1).ToString();
  base.OnLoad(e);
}
</script>
<html>
  <body>
    <form runat="server">
      <h2>ViewState test page</h2>
      <span id="_sum" runat="server">0</span>
      <br />
      <input type="submit" />
    </form>
  </body>
</html>

  每次按下 Submit 按鈕時,_sum 範圍值遞增。因為 ViewState 在請求期間保持以前的值,因此它將從上一次顯示的值開始,顯示 1、2、3、4 等等。如果想知道 ViewState 不可用時發生的事情,嘗試添加 enableviewstate='false' 作為範圍元素的一個屬性。因為以前的範圍值在請求處理時沒有傳播,所以不論頁面發布多少次,都將顯示值為 1。

  在 ASP.NET 中, ViewState 完成基於控制項的編程模型。如果沒有 ViewState ,一些控制項(如文字框和下拉式清單)在 POST 請求期間保持狀態,而其他控制項不保持,使用這些狀態各異的控制項記錄一些特殊的情況是令人沮喪的體驗。使用 ViewState ,開發人員能夠專註於編程模型和使用者介面,而不用擔心狀態保持。還能對 ViewState 進行雜湊或加密,以防止使用者篡改或解碼。

  使用 ViewState 的另一個重要之處是在控制項中發行伺服器端變更事件。如果使用者改變了文字框中的值或切換了下拉式清單中的選定元素,您就能夠註冊一個事件處理常式,引發事件時,執行代碼。這些控制項比較其當前值與以前值,如果有任何過程預訂變更事件,以前值隱式儲存在 ViewState 中。如果禁用一個控制項的 ViewState ,而您正在處理該控制項的更改通知事件,因為總是假定以前值與表單預設值相同,所以更改通知事件不會正確激發。

  ViewState 問題

  正如我早前指出的,在 ASP.NET 1.x 中, ViewState 有很多問題。預設情況下,它是啟用的,除非您知道在不需要使用時找到並禁用它,否則它能顯著增加頁面呈現的資料量。當使用資料繫結控制項時,所有控制項都使用 ViewState 儲存回傳後的狀態,這將變得異常痛苦。作為一個簡單而生動的樣本,ASP.NET 頁面代碼:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Configuration" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<script language="C#" runat="server">
protected override void OnLoad(EventArgs e)
{
  string dsn = ConfigurationSettings.AppSettings["dsnPubs"];
  string sql = "SELECT * FROM Authors";
 
  using (SqlConnection conn = new SqlConnection(dsn))
  using (SqlCommand cmd = new SqlCommand(sql, conn))
  {
    conn.Open();
    _dg1.DataSource = cmd.ExecuteReader();
    _dg1.DataBind();
  }
  base.OnLoad(e);
}
</script>
<html>
  <body>
    <form id="Form1" runat="server">
      <asp:DataGrid ID="_dg1" Runat="server" />
    </form>
  </body>
</html>

  這個頁面有一個 DataGrid 控制項,該控制項綁定對 pubs 資料庫中 authors 表格進行簡單查詢的結果。如果運行這個頁面(對連接字串做出必要改正),查看 ViewState 欄位,您可能吃驚地發現裡面有超過 12,000 個字元。當查看頁面內容,意識到顯示瀏覽器中整個表格內容所需的實際字元數量大約是 1,600,您會更加吃驚。造成這個結果的原因之一是 ViewState 不僅編碼資料,而且編碼資料類型(中繼資料);同樣,Base 64 編碼一般要增加大約 33 % 的空間系統開銷。而且,大量的系統開銷只是為了保留 POST 請求後的控制項狀態,這似乎與時間不成比例,必須竭盡全力避免發生。

  很明顯,如果您關心響應大小,那麼決定何時禁用控制項的 ViewState 是重要的。剛才的樣本就是一個典型的情況,傳播了 ViewState ,但是從未使用,這是最佳化網站的 ViewState 使用時建議採用的主要規則:如果每次請求頁面時填充控制項內容,禁用該控制項的 ViewState 一般是安全(而明智)的。

  另一方面,您可能決定利用 ViewState 保留控制項狀態這一實事,並且只在頁面的首次 GET 請求時,填充控制項內容(只是貫穿後續 POST 請求)。這省去了使用的任何後端資料來源的往返行程。通過修改我的頁面來利用這一結論,我更改了 OnLoad 方法,使它在填充 DataGrid 前檢查 IsPostBack 標誌,如以下代碼所示。

protected override void OnLoad(EventArgs e)
{
  if (!IsPostBack)
  {
    string dsn = ConfigurationSettings.AppSettings["dsnPubs"];
    string sql = "SELECT * FROM Authors";
    using (SqlConnection conn = new SqlConnection(dsn))
    using (SqlCommand cmd = new SqlCommand(sql, conn))
    {
      conn.Open();
      _dg1.DataSource = cmd.ExecuteReader();
      _dg1.DataBind();
    }
  }
  base.OnLoad(e);
}

  當然,有一些其他可能更好的選擇,例如快取服務器的查詢結果,每次發出請求時重新繫結控制項。由您權衡狀態儲存的位置和特定體繫結構與應用程式的重要性。

  您可能注意到我曾小心提過,如果每次請求頁面時填充控制項內容,那麼禁用 ViewState “一般”是安全的。例外情況是,一些控制項既使用 ViewState 保留行為,也保留一般狀態。如前所述,下拉式清單和文字框控制項使用 ViewState 儲存以前的值來正確發行伺服器上的更改通知事件。同樣地,DataGrid 類使用 ViewState 發布分頁、編輯和排序事件。遺憾的是,如果您想要使用 DataGrid 中諸如排序、分頁或編輯的功能,則不能禁用其 ViewState 。對於嘗試產生快速有效網站的開發人員來說,伺服器端控制項 ViewState 的非全有即全無的狀況,是 ASP.NET 1.x 的伺服器端控制項模型另人沮喪的一面。

[1] [2] [3] 下一頁  



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.