本篇介绍如何藉由改善 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 的值存在实体空间中(如硬碟),如何才是 最好的作法,并无一定定论,要视系统环境、使用者使用习惯而定。