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

  好了,下面具体展开吧!

  一,viewstate压缩:

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

protected override void SavePageStateToPersistenceMedium(object state){StringBuilder sb = new StringBuilder();TextWriter tw = new StringWriter(sb);LosFormatter lf = new LosFormatter();lf.Serialize(tw, state);tw.Flush();tw.Close();tw.Dispose();bool useZip = false;string finalStr = sb.ToString();if (sb.Length >= 1096){useZip = true;byte[] bytes = Compress(Convert.FromBase64String(finalStr));finalStr = Convert.ToBase64String(bytes);}ClientScript.RegisterHiddenField("_MyViewState", finalStr);ClientScript.RegisterHiddenField("_UseZip", (useZip?"T":"F"));}private byte[] Compress(byte[] data){MemoryStream ms = new MemoryStream();GZipStream gzip = new GZipStream(ms, CompressionMode.Compress);gzip.Write(data, 0, data.Length);gzip.Flush();gzip.Close();gzip.Dispose();byte[] bytes = ms.ToArray();ms.Close();ms.Dispose();return bytes;}

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

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

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

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

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

protected override object LoadPageStateFromPersistenceMedium(){string myViewState = Request.Form["_MyViewState"];bool useZip = (Request.Form["_UseZip"].Equals("T")?true:false);LosFormatter lf = new LosFormatter();if (useZip){byte[] bytes = Convert.FromBase64String(myViewState);bytes = Decompress(bytes);return lf.Deserialize(Convert.ToBase64String(bytes));}else{return lf.Deserialize(myViewState);}}private byte[] Decompress(byte[] data){MemoryStream ms = new MemoryStream(data);GZipStream gzip = new GZipStream(ms, CompressionMode.Decompress);byte[] resultByte = null;int count = 1;MemoryStream resultMs = new MemoryStream();while (count >= 1){resultByte = new byte[1024];count = gzip.Read(resultByte, 0, 1024);resultMs.Write(resultByte, 0, count);}resultByte = resultMs.ToArray();resultMs.Close();resultMs.Dispose();gzip.Close();gzip.Dispose();ms.Close();ms.Dispose();return resultByte;}

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

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

  二,后置ViewState(2011.12.12校正)

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

protected override void Render(HtmlTextWriter writer){StringWriter sw = new StringWriter();HtmlTextWriter htw = new HtmlTextWriter(sw);base.Render(htw);htw.Flush();htw.Close();htw.Dispose();StringBuilder resulteHtml = new StringBuilder(sw.ToString());sw.Close();sw.Dispose();Regex reg = new Regex("<input type=\"hidden\" name=\"_MyViewState\" id=\"_MyViewState\" .* />");string myViewState = reg.Match(resulteHtml.ToString()).Value;if(!string.IsNullOrEmpty(myViewState)){resulteHtml.Replace(myViewState, string.Empty);resulteHtml.Append(myViewState);//不能把自定义隐藏控件放在页面的最后int formEndTag_index=resulteHtml.ToString().IndexOf("</form>");resulteHtml.Insert(forEndTag_index,myViewState);reg = new Regex("<input type=\"hidden\" name=\"_UseZip\" id=\"_UseZip\" .* />");myViewState = reg.Match(resulteHtml.ToString()).Value;resulteHtml.Replace(myViewState, string.Empty);resulteHtml.Append(myViewState);//不能把自定义隐藏控件放在页面的最后formEndTag_index=resulteHtml.ToString().IndexOf("</form>");resulteHtml.Insert(forEndTag_index,myViewState);}Response.Write(resulteHtml.ToString());}
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控件内的更新、删除操作失效,原因暂时不清楚,大家有没有好方法啊??请告诉我吧!~~

网页优化系列三:使用压缩后置viewstate相关推荐

  1. 游戏优化系列三:Unity游戏的黑屏问题解决方法

    作者 大家好,我叫Jack冯: 本人20年硕士毕业于广东工业大学,于2020年6月加入37手游安卓团队:目前主要负责海外游戏发行安卓相关开发. 系列目录 游戏优化系列一:海外谷歌应用适配相关 游戏优化 ...

  2. 小米10T系列新机曝光:后置64MP三摄 辨识度超高

    今年小米共推出了四款小米10系列机型,包括小米10.小米10 Pro.小米10青春版和小米10至尊纪念版,尤其致敬小米10周年的小米10至尊纪念版受到了用户和媒体的高度关注.而在不久前,小米10系列又 ...

  3. 华为怎么显示返回按键_华为Mate 40系列再曝:后置六摄、或升级90Hz屏

    随着时间的推进,各品牌陆续带来了下半年的旗舰产品.除了大家比较熟悉的三星.苹果.一加外,华为也即将带来全新的旗舰系列新机. 不久前,华为正式宣布将于10月22日带来华为Mate 40系列全球线上发布会 ...

  4. SharePoint 2007 Web Content Management 性能优化系列 3 - IIS压缩

    IIS压缩并不是一项新技术,但对于SharePoint站点而言,IIS压缩能起到很大的作用.在IIS服务器上启用IIS压缩功能之后,在IIS服务器把页面内容发送给浏览器之前,会在服务器上先把内容进行压 ...

  5. 【Spring注解系列11】Spring后置处理器BeanPostProcessor用法与原理

    1.BeanPostProcessor原理 先说,bean的后置处理器BeanPostProcessor接口中两个方法: postProcessBeforeInitialization:在初始化之前工 ...

  6. ElasticSearch优化系列三:索引过程

    大家可能会遇到索引数据比较慢的过程.其实明白索引的原理就可以有针对性的进行优化.ES索引的过程到相对Lucene的索引过程多了分布式数据的扩展,而这ES主要是用tranlog进行各节点之间的数据平衡. ...

  7. ElasticSearch优化系列三:机器设置(内存)

    heap参数设置优化 命令行修改 ./bin/elasticsearch -Xmx10g -Xms10g xmx-JVM最大允许分配的堆内存,按需分配 xms-JVM初始分配的堆内存 此值设置与-Xm ...

  8. iPhone 12顶配版延期到10月:刘海仍在 后置3摄+雷达

    根据现在比较一致的消息,今年秋季苹果的年度旗舰iPhone 12系列将提供iPhone 12(5.4英寸).iPhone 12 Plus(6.1英寸).iPhone 12 Pro(6.1英寸).iPh ...

  9. spring源码:九大后置处理器

    目的: spring在完成一个bean的初始化.实例化的过程中,会用到九个后置处理器:本文梳理出这九个后置处理器 九大后置处理器 spring在初始化的过程中,会在九个地方分别调用了五个后置处理的九个 ...

最新文章

  1. MYSQL修改配置,允许远程访问
  2. 利用Docker设置Node.js
  3. 使用python进行面部合成,比PS好用多了
  4. vue赋值与ajax什么区别,Vue中ajax返回的结果赋值
  5. 二叉树的前中后序遍历之迭代法(非统一风格迭代方式)
  6. Metasploit--后渗透(一些基本操作方法)
  7. 认真测试直播软件,直播这么火,你知道怎么测试直播软件吗?
  8. 删除Dataframe前N行或后N行
  9. antd vue关闭模态对话框_我不能没有的5个Vue.js库
  10. (带区号)座机号正则_字符串处理之正则表达式(通俗易懂)
  11. HCIE-Security Day38:理论学习:信息安全管理
  12. VM14安装Mas os 13
  13. 只有运用你的逻辑才能看懂其中的恐怖及答案
  14. bat快捷方式启动局域网共享文件
  15. VBA下载文件 使用WebBrowser 及 DoFileDownload
  16. Inno Setup 介绍
  17. Qt学习总结之QTableWidget表格填充
  18. C#实现屏幕键盘(软键盘 ScreenKeyboard)
  19. sunspot solr
  20. BW型、CB I型、CB II型和椭圆模拟低通滤波器设计的Matlab仿真

热门文章

  1. 剑指offer面试题[40]-数组中只出现一次的数字
  2. 墙式微型计算机,小学微机室墙面布置
  3. java应用中spring自动注入_Spring自动注入的几种方式
  4. java email怎么设置端口号_java mail 设置参数
  5. 一种结合实例和语义分割从田间图像中识别咖啡叶病虫害的深度学习方法
  6. NCFM识别-Googlenet
  7. 股市舆情情感分类可视化系统
  8. php pod模式,k8s pod的4种网络模式最佳实战(externalIPs )
  9. java -虹软Caused by: java.lang.UnsatisfiedLinkError: Can‘t load library: **\WIN64\libarcsoft_face.dll
  10. html5中可用的颜色,jquery – 如何知道HTML5输入类型颜色是否可用作颜色选择器?...