zoukankan      html  css  js  c++  java
  • Asp.Net中压缩ViewState的2种方法

    asp.net ViewState 是一种新的状态服务,可供开发人员基于每个用户来跟踪 UI 状态,该辅助数据被存储在一个名为 __VIEWSTATE 的隐藏字段中。

    当然, ViewState 在 ASP.NET 中有个重要的角色。如果使用恰当,它能够简化页面开发,改进用户与站点的交互。如果置之不理,它能够显着增加站点响应大小,在连接速度慢的情况下,使您的响应时间更加缓慢。因为浏览器的每次回发都会导致ViewState 逐渐增加您的页面大小,从而导致性能问题。因此,ASP.NET 2.0 的发布带来了 ViewState 机制的一些改进,这使得 ViewState 使用更简单,又不会防碍站点性能。这些改进包括:减少编码数量,采用控件状态从内容中分离出行为状态,以及智能集成数据绑定控件。你可以在不需要维护控件状态的情况下通过禁用的控件(EnableViewState = false )解决这个问题。 然而,很多情况下保持控件的状态是必需的,压缩的ViewState有助于提高性能。

    方法一:使用System.IO.Compression

    System.IO.Compression 命名空间包含提供基本的流压缩和解压缩服务的类。

    此命名空间包含2个类分别为:

    DeflateStream 提供用于使用 Deflate 算法压缩和解压缩流的方法和属性。

    GZipStream 提供用于压缩和解压缩流的方法和属性。

    在下面的演示代码中,我们创建一个ViewStateCompression类,包含2个方法,并都返回byte[]数据:

    1.GZipStream版的压缩/解压缩

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.IO;
    using System.IO.Compression;
    
    /// <summary>
    ///ViewStateCompression 的摘要说明
    /// </summary>
    public class ViewStateCompression
    {
        public ViewStateCompression()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }
        // 压缩
        public static byte[] Compress(byte[] data)
        {
            MemoryStream output = new MemoryStream();
            GZipStream gzip = new GZipStream(output,
            CompressionMode.Compress, true);
            gzip.Write(data, 0, data.Length);
            gzip.Close();
            return output.ToArray();
        }
    
        // 解压缩
        public static byte[] Decompress(byte[] data)
        {
            MemoryStream input = new MemoryStream();
            input.Write(data, 0, data.Length);
            input.Position = 0;
            GZipStream gzip = new GZipStream(input,
            CompressionMode.Decompress, true);
            MemoryStream output = new MemoryStream();
            byte[] buff = new byte[64];
            int read = -1;
            read = gzip.Read(buff, 0, buff.Length);
            while (read > 0)
            {
                output.Write(buff, 0, read);
                read = gzip.Read(buff, 0, buff.Length);
            }
            gzip.Close();
            return output.ToArray();
        }
    }

    2.执行ViewStateCompression类

      想使用ViewStateCompression的压缩和解压页面ViewState的功能,我们必须重写 System.Web.UI.Page 的 SavePageStateToPersistenceMedium() 和LoadPageStateFromPersistenceMedium() 方法。

      SavePageStateToPersistenceMedium 方法 可以反序列化的ViewState,它接受一个 ViewState对象的参数。

      LoadPageStateFromPersistenceMedium 方法 可以序列化ViewState,它接受一个Base64编码的字符串参数。

      重写代码如下,新建了一个继承与System.Web.UI.Page的BasePage类:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    using System.IO;
    using System.Web.UI;
    
    /// <summary>
    ///BasePage 的摘要说明
    /// </summary>
    public class BasePage : System.Web.UI.Page
    {
        public BasePage()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }
        protected override void SavePageStateToPersistenceMedium(object pageViewState)
        {
            LosFormatter losformatter = new LosFormatter();
            StringWriter sw = new StringWriter();
            losformatter.Serialize(sw, pageViewState);
            string viewStateString = sw.ToString();
            byte[] b = Convert.FromBase64String(viewStateString);
            b = ViewStateCompression.Compress(b);
            // ----ClientScript.RegisterHiddenField("__ZIPSTATE", Convert.ToBase64String(b));
            //
            // 兼容ASP.NET Ajax 的ViewState压缩
            ScriptManager.RegisterHiddenField(this, "__ZIPSTATE", Convert.ToBase64String(b));
        }
    
        // 序列化ViewState
    
        protected override object LoadPageStateFromPersistenceMedium()
        {
            string custState = Request.Form["__ZIPSTATE"];
            byte[] b = Convert.FromBase64String(custState);
            b = ViewStateCompression.Decompress(b);
            LosFormatter losformatter = new LosFormatter();
            return losformatter.Deserialize(Convert.ToBase64String(b));
        }
    
    }

      经过上述的方法后,你的ViewState可能会减少30-40%.

      3.ViewState SEO

      ViewState会影响SEO,当然,影响并不是很大。搜索引擎在搜录页面的时候,从页面源文件第一个字符开始,到100K的位置,后面的收录不是很友好,甚至还会出现收录问题。因此,在前100K的时候,我们可以考虑将ViewState 移到页面的底部, 之前。参考代码请下载本文的示例,这里给出效果图参考:

        

      移动之前:

        

      移动后:

        

      方法二:使用session完全删除ViewState

      使用这个方法即可以完全删除ViewState,又可以完全保存ViewState的优势,还可以减少客户端要求下载的多余字节,还可以搜索引擎解决收录问题。原理是通过利用Session允许在服务器上保存ViewState的方法重写上面的SavePageStateToPersistenceMedium() 和LoadPageStateFromPersistenceMedium() 方法。

    改写上面的方法后的代码如下:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    
    using System.IO;
    using System.Web.UI;
    
    /// <summary>
    ///BasePage 的摘要说明
    /// </summary>
    public class BasePage:System.Web.UI.Page
    {
        public BasePage()
        {
            //
            //TODO: 在此处添加构造函数逻辑
            //
        }
        protected override void SavePageStateToPersistenceMedium(object pageViewState)
        {
            MemoryStream ms = new MemoryStream();
            LosFormatter m_formatter = new LosFormatter();
            m_formatter.Serialize(ms, pageViewState);
            ms.Position = 0;
            StreamReader sr = new StreamReader(ms);
            string viewStateString = sr.ReadToEnd();
            byte[] ViewStateBytes = Convert.FromBase64String(viewStateString);
            ViewStateBytes = ViewStateCompression.Compress(ViewStateBytes);
            Session["ViewState"] = Convert.ToBase64String(ViewStateBytes);
            ms.Close();
            return;
        }
    
        // 序列化ViewState
        protected override object LoadPageStateFromPersistenceMedium()
        {
            object viewStateBag;
            string m_viewState = (string)Session["ViewState"];
            byte[] ViewStateBytes = Convert.FromBase64String(m_viewState);
            ViewStateBytes = ViewStateCompression.Decompress(ViewStateBytes);
            LosFormatter m_formatter = new LosFormatter();
            try
            {
                viewStateBag = m_formatter.Deserialize(Convert.ToBase64String(ViewStateBytes));
            }
            catch (Exception ex)
            {
                //Log.Insert( "页面Viewtate是空。" );
                viewStateBag = string.Empty;
            }
            return viewStateBag;
        }
    }
    
     

      改写后我们可以从下图看到ViewState完全被删除了,而且传输到客户端的数据从1006B 减少 到750B,这在页面中很多数据源控件时,将提高了一定性能:

     

     

  • 相关阅读:
    ExecuteScalar requires the command to have a transaction when the connection assigned to the command is in a pending
    如何从vss中分离程序
    String or binary data would be truncated
    the pop3 service failed to retrieve authentication type and cannot continue
    The POP3 service failed to start because
    IIS Error he system cannot find the file specified _找不到页面
    pku2575Jolly Jumpers
    pku2940Wine Trading in Gergovia
    pku3219二项式系数
    pku1029false coin
  • 原文地址:https://www.cnblogs.com/liyuxin/p/2495542.html
Copyright © 2011-2022 走看看