网页优化系列三:使用压缩后置viewstate

简介:

Asp.net中的服务器控件都启用了viewstate,虽然方便了开发人员,但页面大小及性能上确实有所影响,对于无需viewstate的控件及页面可以直接把控件或页面的viewstate禁用掉,但对于必须的viewstate我们可以采取另一种方式来处理——压缩。判断是否需要viewstate压缩准则是,内网系统不必考虑压缩(网速够快还闲着没事消耗服务器CPU资源干啥啊。。。),对外系统根据viewstate长度选择性进行压缩(当viewstate长度大于某个值时进行压缩,太短还压缩得不偿失哦。。。)

  好了,下面具体展开吧!

  一,viewstate压缩:

  页面的生存周期里保存viewstate的方法为SavePageStateToPersistenceMedium方法,所以重写这个方法就ok了。

复制代码
 1  protected override void SavePageStateToPersistenceMedium(object state)
2 {
3 StringBuilder sb = new StringBuilder();
4 TextWriter tw = new StringWriter(sb);
5 LosFormatter lf = new LosFormatter();
6 lf.Serialize(tw, state);
7 tw.Flush();
8 tw.Close();
9 tw.Dispose();
10 bool useZip = false;
11 string finalStr = sb.ToString();
12 if (sb.Length >= 1096)
13 {
14 useZip = true;
15 byte[] bytes = Compress(Convert.FromBase64String(finalStr));
16 finalStr = Convert.ToBase64String(bytes);
17 }
18
19 ClientScript.RegisterHiddenField("_MyViewState", finalStr);
20 ClientScript.RegisterHiddenField("_UseZip", (useZip?"T":"F"));
21 }
22
23 private byte[] Compress(byte[] data)
24 {
25 MemoryStream ms = new MemoryStream();
26 GZipStream gzip = new GZipStream(ms, CompressionMode.Compress);
27 gzip.Write(data, 0, data.Length);
28 gzip.Flush();
29 gzip.Close();
30 gzip.Dispose();
31
32 byte[] bytes = ms.ToArray();
33 ms.Close();
34 ms.Dispose();
35
36 return bytes;
37 }
复制代码

1.传入的参数state就是页面所有的viewstate集合对象,默认时该对象是经过序列化后保存到__ViewState的隐藏控件中的。所以要用LosFormatter对象将将state对象序列化,此时得到的序列化字符串是68位的数为基来编码的。

2.1096表示当viewstate长度大于1096时就压缩,否则就原封不动。

3..net有的System.IO.Compression中有两种压缩方式,这里选用GZip,也可以用其他更好的压缩算法的方法,压出效果就好^_^!

4.压缩完后恢复成以68位的数为基的编码字符串保存到__MyViewState的隐藏控件中,注意不能用回默认的__ViewState保存,否则会出错。

 

搞定压缩部分,当然都解压部分啦,回传时通过LoadPageStateFromPersistenceMedium方法获取viewstate,所以继续重写吧

复制代码
 1   protected override object LoadPageStateFromPersistenceMedium()
2 {
3 string myViewState = Request.Form["_MyViewState"];
4 bool useZip = (Request.Form["_UseZip"].Equals("T")?true:false);
5 LosFormatter lf = new LosFormatter();
6 if (useZip)
7 {
8 byte[] bytes = Convert.FromBase64String(myViewState);
9 bytes = Decompress(bytes);
10
11 return lf.Deserialize(Convert.ToBase64String(bytes));
12 }
13 else
14 {
15 return lf.Deserialize(myViewState);
16 }
17 }
18 private byte[] Decompress(byte[] data)
19 {
20 MemoryStream ms = new MemoryStream(data);
21 GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress);
22 byte[] resultByte = null;
23 int count = 1;
24 MemoryStream resultMs = new MemoryStream();
25 while (count >= 1)
26 {
27 resultByte = new byte[1024];
28 count = gzip.Read(resultByte, 0, 1024);
29 resultMs.Write(resultByte, 0, count);
30 }
31 resultByte = resultMs.ToArray();
32 resultMs.Close();
33 resultMs.Dispose();
34 gzip.Close();
35 gzip.Dispose();
36 ms.Close();
37 ms.Dispose();
38
39 return resultByte;
40 }
复制代码

1.从__MyViewState中获取viewstate字符串,然后是解压、反序列,得到之前保存的ViewState对象。

 

这样ViewState的压缩就KO了。当然Asp.net还可以将ViewState保存到Session里面,设置一下就好了,非常方便,也免得自己来处理多页面出现的ViewState覆盖问题。

 

  二,后置ViewState(2011.12.12校正)

viewstate默认是保存到页面的开头部分,如果长度过大会对搜索引擎爬该网站有一定的影响,可以通过把ViewState放置到页面最后的方式优化,后置viewstate还有一个好处就是页面会出来快一点哦。

复制代码
 1  protected override void Render(HtmlTextWriter writer)
2 {
3 StringWriter sw = new StringWriter();
4 HtmlTextWriter htw = new HtmlTextWriter(sw);
5 base.Render(htw);
6 htw.Flush();
7 htw.Close();
8 htw.Dispose();
9 StringBuilder resulteHtml = new StringBuilder(sw.ToString());
10 sw.Close();
11 sw.Dispose();
12
13 Regex reg = new Regex("<input type=\"hidden\" name=\"_MyViewState\" id=\"_MyViewState\" .* />");
14 string myViewState = reg.Match(resulteHtml.ToString()).Value;
       if(!string.IsNullOrEmpty(myViewState))
      {
15   resulteHtml.Replace(myViewState, string.Empty);
16 resulteHtml.Append(myViewState);//不能把自定义隐藏控件放在页面的最后
         int formEndTag_index=resulteHtml.ToString().IndexOf("</form>");
             resulteHtml.Insert(forEndTag_index,myViewState);
17           reg = new Regex("<input type=\"hidden\" name=\"_UseZip\" id=\"_UseZip\" .* />");
18   myViewState = reg.Match(resulteHtml.ToString()).Value;
19   resulteHtml.Replace(myViewState, string.Empty);
20 resulteHtml.Append(myViewState);//不能把自定义隐藏控件放在页面的最后
 
  
         formEndTag_index=resulteHtml.ToString().IndexOf("</form>");
 
  
             resulteHtml.Insert(forEndTag_index,myViewState);
       }

21 Response.Write(resulteHtml.ToString());
22 }
复制代码
Render是页面发送给用户前最后留给我们发挥的地方了(除了自定义HttpModule啦),base.Render()会将页面控件所生成的html代码输入到HtmlTextWriter
对象中,通过它就可以得到页面最终的html代码了,接着就用正则表达式获取viewstate部分,并移动到html代码的最后,然后直接输出到响应流中,至于重写方
法中的参数,就当作路人甲乙丙吧。
2011.12.12校正部分:
   1.若直接把自定义隐藏控件保存到html代码末尾结果为:....</form><input type="hidden" id="_MyViewState" name="_MyViewState"... ,
当postback时在LoadPageStateFromPersistenceMedium时因隐藏控件在form之外,所以无法用form["参数命"]来获取。因此要将自定义隐藏控件放在</form
>标签之前。

   2.判断myViewState是否为空字符串目的是,当使用ajax.net时render所得到的内容并不包含之前自定义的隐藏控件,防止string.replace中oldvalue为空时抛出异常。

  3.当页面使用ajax.net时并且使用该基类对viewstate作处理,会出现UpdatePanel控件内的更新、删除操作失效,原因暂时不清楚,大家有没有好方法啊??请告诉我吧!~~



下一篇:网页优化系列四:Asp.Net的5种缓存方式

如果您觉得本文的内容有趣就扫一下吧!捐赠互勉!

本文转自^_^肥仔John博客园博客,原文链接:http://www.cnblogs.com/fsjohnhuang/archive/2011/12/09/2282325.html,如需转载请自行联系原作者


相关文章
|
5月前
|
前端开发 UED
一个页面上有大量的图片,加载很慢,你有哪些方法优化这些图片的加载?
一个页面上有大量的图片,加载很慢,你有哪些方法优化这些图片的加载?
|
6天前
|
缓存 前端开发 JavaScript
如何优化网页加载速度?
【5月更文挑战第8天】如何优化网页加载速度?
11 2
|
19天前
|
存储 缓存 前端开发
提高网页加载速度可以从以下几个方面进行优化
【4月更文挑战第25天】提高网页加载速度可以从以下几个方面进行优化
20 5
|
3月前
|
存储 缓存 前端开发
JavaScrip实现一个有时间限制的缓存类
JavaScrip实现一个有时间限制的缓存类
18 0
|
7月前
|
前端开发 JavaScript Java
70jqGrid - 一次性加载多级表格数据
70jqGrid - 一次性加载多级表格数据
21 0
|
8月前
|
缓存 前端开发 算法
如何优化网页加载速度
在今天互联网高速发展的时代,快速加载网页成为了用户体验的重要因素之一。如果一个网页加载速度过慢,不仅会让用户感到烦躁,还可能导致用户流失和降低搜索引擎排名。因此,优化网页加载速度变得至关重要。
91 0
|
9月前
|
小程序 JavaScript 前端开发
小程序实现滚动加载(懒加载)
小程序是一项很受欢迎的技术,随着其能力的不断增强,越来越多的人开始使用小程序来完成各种任务。当我面面临一个页面有非常多的数据时,该如何处理呢,显然一次性全部加载完,会非常消耗性能的,为了解决这些问题从而出现了一种叫滚动加载的数据处理方式,也被称为“无限滚动”或“懒加载”,它可以使你的页面在不刷新的情况下连续加载更多数据。在本文中,我们将讨论如何在小程序中实现滚动加载。
216 0
|
PHP 计算机视觉
yii2.0上传图片的时候如何实现自动压缩?
yii2.0上传图片的时候如何实现自动压缩?
233 0
|
JSON 前端开发 JavaScript
EasyUI–表单加载内存/本地/服务端数据
在不使用前端语言JS(jQuery等前端框架本质上也是JS)时,如果我们想往表单里面放入数据,该怎么办?比如从文件中、从数据库查出用户信息显示在表单中。
482 0
EasyUI–表单加载内存/本地/服务端数据
fbh
|
缓存 JavaScript 前端开发
常用优化网页加载速度方法
许多研究发现,页面速度和访客的滞留时间,跳出率以及收入都有直接的关系。另外,谷歌的排名算法中也把页面加载速度作为其中一项考虑因素。
fbh
3258 0