用 ASP.NET 2.0 改进的 ViewState 加快网站速度

asp.net|速度

    如果您是个经验丰富的 ASP.NET 开发人员,一提起 ViewState ,您可能会不寒而栗,因为您想到的是大量通过“鸡尾酒吸管”吸入的 Base64 编码数据。除非采取步骤进行预防,否则大部分 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 不仅编码数据,而且编码数据类型(元数据);同样,Base64 编码一般要增加大约 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] 下一页  

时间: 2024-08-22 14:28:20

用 ASP.NET 2.0 改进的 ViewState 加快网站速度的相关文章

ASP.NET 2.0主题和皮肤实现网站美化

asp.net 主题和外观是ASP.NET 2.0 中的新增功能, 使用 ASP.NET 2.0 的"主题和外观"功能,可以将样式和布局信息分解为单独的文件组,统称为"主题".然后,主题可应用于任何站点,影响站点中页和控件的外观.这样,通过更改主题即可轻松地维护对站点的样式更改,而无需对站点各页进行编辑.还可与其他开发人员共享主题.应用 ASP.NET 2.0的"主题和外观"功能轻松实现对网站美观的控制. ASP.NET 提供了一些可在应用程序中

用ASP.NET 2.0主题和皮肤实现网站美化

主题和外观是ASP.NET 2.0 中的新增功能, 使用 ASP.NET 2.0 的"主题和外观"功能,可以将样式和布局信息分解为单独的文件组,统称为"主题".然后,主题可应用于任何站点,影响站点中页和控件的外观.这样,通过更改主题即可轻松地维护对站点的样式更改,而无需对站点各页进行编辑.还可与其他开发人员共享主题.应用 ASP.NET 2.0的"主题和外观"功能轻松实现对网站美观的控制. ASP.NET 提供了一些可在应用程序中对页和控件的外观

ASP.NET 2.0的编译模型

ASP.NET 2.0支持两种编译模型(Compilation Model):一为动态编译 (Dynamic Compilation),另一个为先行编译(Precompilation). 这让程序设计师可以有更宽广的选择以决定不同网站何时该用何种编译模型 ,不但弹性大大提升,且若采用先行编译网站执行效能还可以更高,分述如下: (一)ASP.NET网站动态编译(Dynamic Compilation) 在ASP.NET 1.0时就已经支持网站动态编译,也就是使用者第一次请求网站网 页时,ASP.N

艾伟:ASP.NET 2.0的编译模型

ASP.NET 2.0支持两种编译模型(Compilation Model): 一为动态编译(Dynamic Compilation),另一个为先行编译(Precompilation). 这让程序设计师可以有更宽广的选择以决定不同网站何时该用何种编译模型,不但弹性大大提升,且若採用先行编译网站执行效能还可以更高,分述如下: (一)ASP.NET网站动态编译(Dynamic Compilation) 在ASP.NET 1.0时就已经支援网站动态编译,也就是使用者第一次请求网站网页时,ASP.NET

探讨ASP.NET 2.0的Web控件改进之概述

asp.net|web|控件 一. 引言 到目前为止,你可能已经了解了大量的ASP.NET 2.0新特征-母版页面,主题,提供者,等等--所有这样内容都相当精彩:但是,你是否了解到有关定制Web控件开发方面的重大变化?这正是我在本文中所想讨论的.如果你已经从事于控件开发,那么,我想本文所描述的ASP.NET 2.0中的新的改进特征会立即应用于你的控件开发中. 首先应该注意的是,你以前使用ASP.NET 1.1(或1.0)开发的所有Web控件在2.0版本下将继续良好运行-微软并没有破坏你的现有代码

探讨ASP.NET 2.0中的Web控件改进技术

asp.net|web|控件 ASP.NET 2.0并没有抛弃1.1版本中的任何现有控件,而是增加了一组新的控件;同时还引入了若干新的控件开发技术.本系列文章将对这些内容展开全面探讨. 一. 引言 到目前为止,你可能已经了解了大量的ASP.NET 2.0新特征-母版页面,主题,提供者,等等--所有这样内容都相当精彩;但是,你是否了解到有关定制Web控件开发方面的重大变化?这正是我在本文中所想讨论的.如果你已经从事于控件开发,那么,我想本文所描述的ASP.NET 2.0中的新的改进特征会立即应用于

Asp.net 2.0 ViewState原理

ViewState相信大家都会使用,可ViewState到底是什么,又有多少人知道呢? StateBag类这个就不用多说啦吧 在Asp.net 2.0 里,用到StateBag有三处 1 Control._viewState  这个就是大家使用的ViewState 2 WebControl.attrState这个是存放Attribute的 3 Style.statebag是存放样式的.......Page生命周期内SaveAllState时 需要先生成个Piar类,在调用this.SavePag

ASP.NET 2.0 中改进的缓存功能

asp.net|缓存 Stephen Walther      Microsoft Corporation      适用于:      Microsoft ASP.NET 2.0      Microsoft ASP.NET Framework      Microsoft SQL Server      Microsoft Visual Studio .NET      摘要:本文中,Stephen Walther 将重点介绍 ASP.NET 2.0 中新增的缓存功能,以及如何使用这些新功能

[转]利用ASP.NET 2.0创建自定义Web控件(2)

原址:http://hi.baidu.com/sjbh/blog/item/5a8298454403a321cffca39c.html   如何生成的? Render() 方法基本上控制着 WebControl 的整个输出.默认情况下,Render() 方法实际上会依次调用 RenderBeginTag().RenderContents() 以及 RenderEndTag().尽管在 ASP.NET 1.x 中调用结构并未变化,但由于该呈现模型,修改这些调用的影响却发生了变化. 您可以覆盖 Re