【问题标题】:Recommendations for reducing the ViewState size on a legacy system减少旧系统上 ViewState 大小的建议
【发布时间】:2012-02-15 22:29:30
【问题描述】:

我已经找到了减少 ViewState 的方法:

但是,由于我所处的情况,我需要最快、最有效的方法来减小 ViewState 的大小。我正在处理的遗留系统很臃肿,并且在多次回发时通常有一个 800Kb+ 的 ViewState。

例如,我很确定在多个回帖上填充包含 100 多个项目的下拉列表是罪魁祸首之一,对吗?

任何建议/建议将不胜感激。

编辑 1 完全禁用 ViewState 似乎不可行。它破坏了所有控件,其中有很多,使页面无法使用。如果这是最好的方法,我应该如何处理所有损坏的控件?

【问题讨论】:

  • 我知道您正在寻找最快的方法,但这里有一些建议。尽可能用它们的 html 等效项替换 Web 控件?此外,如果您使用大量面板,请将它们替换为 div。在不需要的控件上禁用视图状态(如果它最终成为页面上的所有控件,也可以通过页面指令应用。

标签: asp.net vb.net optimization drop-down-menu viewstate


【解决方案1】:

如果您有包含许多项目的下拉列表,并且如果这些下拉列表的内容可以在页面回发中轻松检索,则不应将此内容放入视图状态。相反,应在每次回发时在服务器上重新填充下拉列表。典型的例子是一个包含 50 个州的下拉列表。将此内容放入视图状态是没有意义的。此数据可以缓存在服务器上,并用于在每次回发时重新填充下拉列表,而不是在每次往返时将此数据来回传递给客户端。

那么,如何在不将内容添加到视图状态且不关闭控件的视图状态的情况下将内容绑定到下拉列表?答案在于对 ASP.Net 事件管道的理解。在 OnInit 页面事件之后调用 TrackViewState() 方法时的 Viewstate 跟踪对象。在 TrackViewState() 执行后以编程方式对控件进行的任何更改都将放入视图状态。因此,如果您在 Page_Load 事件中对下拉列表进行数据绑定,下拉列表的全部内容将被放入您通常不想要的视图状态。

因此,如果您不希望将下拉列表内容序列化为视图状态,则必须在执行 TrackViewState() 方法之前进行数据绑定。执行此操作的最佳位置是在下拉列表的 Init 事件中。所以长话短说,在它的初始化中填充你的下拉列表,下拉列表的内容不会被序列化到视图状态中。当然,由于内容不在视图状态中,您需要在每次回发时重新填充它。但是,如果内容被缓存并且检索起来很便宜(例如,50 个状态的列表就是这种情况),那么这不是问题。

示例:假设您有一个名为“dropDownList1”的下拉列表,您可以在名为 GetData() 的方法中检索包含列表内容的列表。您可以在 page_load 事件中填充此列表:

    protected void Page_Load(object sender, EventArgs e)
    {
        //Content of dropdown list will be serialized into viewstate
        dropDownList1.DataSource = GetData();
        Page.DataBind();
    }

但如果你这样做,内容将被序列化为视图状态。如果您在其 Init 事件中填充列表:

    protected void dropDownList1_Init(object sender, EventArgs e)
    {
       //Content of dropdown list will NOT be serialized into viewstate
       GetData().ForEach(item => this.dropDownList1.Items.Add(item));
    }

内容不会被序列化为视图状态。只要检索此内容的成本较低,您就应该这样做。

有关这方面的更多信息,请参阅 Infinities Loop 上的 this excellent article。这是我见过的关于视图状态的最好的文章,通过了解这篇文章的内容,我们能够开始在我们的网页上更智能地使用视​​图状态并显着减小视图状态的大小。

【讨论】:

  • 这非常有帮助,尤其是这篇文章。我现在遇到的一个问题是我正在使用当前用户信息填充下拉列表,在页面加载之前我无法访问这些信息。不过仍在试验中……
  • 是的,这可能是个问题。通过在 TrackViewState 执行之前加载下拉列表,您必须在 ASP.Net 事件管道中尽早移动,有时有些东西不可用。通常,如果您考虑一段时间,您可以找到一些解决此类问题的方法。
【解决方案2】:

您可能希望查看this code project 页面上描述的压缩视图状态。

注意:我还没有尝试过,但它似乎应该可以工作。

【讨论】:

  • 绝对是最快减小 ViewState 大小的方法。我在实施该解决方案的 VB.NET 版本时减少了 70%。也就是说,当然需要其他改进。谢谢!
  • 压缩 ViewState 并不一定会导致 HTTP 减少。请记住,HTTP 已经可以(并且应该!)使用 deflate。因此,“预压缩”的 ViewState 可能 [稍微] 不太可压缩..因此请检查发送的 真实 数字。
【解决方案3】:

最快和最有效的方法是完全关闭视图状态:

<system.web>
    <pages enableViewState="false" />

您也可以为个别页面关闭它:

private void Page_Init(object sender, System.EventArgs e)
{
    this.EnableViewState = false;
}

【讨论】:

  • 这也会有效地破坏页面吗?
  • 也许,但你可以看看它们是否跑得更快。然后你就会知道是 ViewState 是罪魁祸首还是你找错了树。
  • 我知道是问题所在。当我查看页面源时,带有id="__VIEWSTATE"input 标签通常非常大。
  • 已确认。禁用 ViewState 会破坏页面上的所有控件。
【解决方案4】:

根据您存储会话的方式(最好存储数据库)、页面获得的流量以及服务器拥有的内存量(如果您使用 InProc 会话),您可以将视图状态存储在会话中.这很容易做到,缺点是存在陷阱,并且不适用于所有网站。

这是一篇很好的文章,概述了该过程的基础知识以及可能存在的一些缺点/陷阱:

http://www.hanselman.com/blog/MovingViewStateToTheSessionObjectAndMoreWrongheadedness.aspx

【讨论】:

    猜你喜欢
    • 2010-12-28
    • 2012-07-09
    • 1970-01-01
    • 2015-08-16
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    • 2012-03-09
    相关资源
    最近更新 更多