当我们压缩我的Response后再传到Client端时,可以明显节省宽带. 提升Site的性能. 现在的浏览器大部分都支持Gzip,Deflate压缩。同时我们还可以删除一些空白段、空行、注释等以使得HTML文档的尺寸变得更小. 让我们先来实现压缩与删除空白类, 继承自Stream类:。
当我们压缩我的Response后再传到Client端时,可以明显节省宽带. 提升Site的性能. 现在的浏览器大部分都支持Gzip,Deflate压缩。同时我们还可以删除一些空白段、空行、注释等以使得HTML文档的尺寸变得更小. 让我们先来实现压缩与删除空白类, 继承自Stream类:
- /// <summary>
- /// CompressWhitespaceFilter
- /// </summary>
- public class CompressWhitespaceFilter : Stream
- {
- private GZipStream _contentGZipStream;
- private DeflateStream _content_DeflateStream;
- private Stream _contentStream;
- private CompressOptions _compressOptions;
- /// <summary>
- /// Initializes a new instance of the <see cref="CompressWhitespaceFilter"/> class.
- /// </summary>
- /// <param name="contentStream">The content stream.</param>
- /// <param name="compressOptions">The compress options.</param>
- public CompressWhitespaceFilter(Stream contentStream, CompressOptions compressOptions)
- {
- if (compressOptions == CompressOptions.GZip)
- {
- this._contentGZipStream = new GZipStream(contentStream, CompressionMode.Compress);
- this._contentStream = this._contentGZipStream;
- }
- else if (compressOptions == CompressOptions.Deflate)
- {
- this._content_DeflateStream = new DeflateStream(contentStream,CompressionMode.Compress);
- this._contentStream = this._content_DeflateStream;
- }
- else
- {
- this._contentStream = contentStream;
- }
- this._compressOptions = compressOptions;
- }
- public override bool CanRead
- {
- get { return this._contentStream.CanRead; }
- }
- public override bool CanSeek
- {
- get { return this._contentStream.CanSeek; }
- }
- public override bool CanWrite
- {
- get { return this._contentStream.CanWrite; }
- }
- public override void Flush()
- {
- this._contentStream.Flush();
- }
- public override long Length
- {
- get { return this._contentStream.Length; }
- }
- public override long Position
- {
- get
- {
- return this._contentStream.Position;
- }
- set
- {
- this._contentStream.Position = value;
- }
- }
- public override int Read(byte[] buffer, int offset, int count)
- {
- return this._contentStream.Read(buffer, offset, count);
- }
- public override long Seek(long offset, SeekOrigin origin)
- {
- return this._contentStream.Seek(offset, origin);
- }
- public override void SetLength(long value)
- {
- this._contentStream.SetLength(value);
- }
- public override void Write(byte[] buffer, int offset, int count)
- {
- byte[] data = new byte[count + 1];
- Buffer.BlockCopy(buffer, offset, data, 0, count);
- string strtext = System.Text.Encoding.UTF8.GetString(data);
- strtext = Regex.Replace(strtext, "^\\s*", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
- strtext = Regex.Replace(strtext, "\\r\\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
- strtext = Regex.Replace(strtext, "<!--*.*?-->", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline);
- byte[] outdata = System.Text.Encoding.UTF8.GetBytes(strtext);
- this._contentStream.Write(outdata, 0, outdata.GetLength(0));
- }
- }
- /// <summary>
- /// CompressOptions
- /// </summary>
- /// <seealso cref="http://en.wikipedia.org/wiki/Zcat#gunzip_and_zcat"/>
- /// <seealso cref="http://en.wikipedia.org/wiki/DEFLATE"/>
- public enum CompressOptions
- {
- GZip,
- Deflate,
- None
- }
/// <summary> /// CompressWhitespaceFilter /// </summary> public class CompressWhitespaceFilter : Stream { private GZipStream _contentGZipStream; private DeflateStream _content_DeflateStream; private Stream _contentStream; private CompressOptions _compressOptions; /// <summary> /// Initializes a new instance of the <see cref="CompressWhitespaceFilter"/> class. /// </summary> /// <param name="contentStream">The content stream.</param> /// <param name="compressOptions">The compress options.</param> public CompressWhitespaceFilter(Stream contentStream, CompressOptions compressOptions) { if (compressOptions == CompressOptions.GZip) { this._contentGZipStream = new GZipStream(contentStream, CompressionMode.Compress); this._contentStream = this._contentGZipStream; } else if (compressOptions == CompressOptions.Deflate) { this._content_DeflateStream = new DeflateStream(contentStream,CompressionMode.Compress); this._contentStream = this._content_DeflateStream; } else { this._contentStream = contentStream; } this._compressOptions = compressOptions; } public override bool CanRead { get { return this._contentStream.CanRead; } } public override bool CanSeek { get { return this._contentStream.CanSeek; } } public override bool CanWrite { get { return this._contentStream.CanWrite; } } public override void Flush() { this._contentStream.Flush(); } public override long Length { get { return this._contentStream.Length; } } public override long Position { get { return this._contentStream.Position; } set { this._contentStream.Position = value; } } public override int Read(byte[] buffer, int offset, int count) { return this._contentStream.Read(buffer, offset, count); } public override long Seek(long offset, SeekOrigin origin) { return this._contentStream.Seek(offset, origin); } public override void SetLength(long value) { this._contentStream.SetLength(value); } public override void Write(byte[] buffer, int offset, int count) { byte[] data = new byte[count + 1]; Buffer.BlockCopy(buffer, offset, data, 0, count); string strtext = System.Text.Encoding.UTF8.GetString(data); strtext = Regex.Replace(strtext, "^\\s*", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline); strtext = Regex.Replace(strtext, "\\r\\n", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline); strtext = Regex.Replace(strtext, "<!--*.*?-->", string.Empty, RegexOptions.Compiled | RegexOptions.Multiline); byte[] outdata = System.Text.Encoding.UTF8.GetBytes(strtext); this._contentStream.Write(outdata, 0, outdata.GetLength(0)); } } /// <summary> /// CompressOptions /// </summary> /// <seealso cref="http://en.wikipedia.org/wiki/Zcat#gunzip_and_zcat"/> /// <seealso cref="http://en.wikipedia.org/wiki/DEFLATE"/> public enum CompressOptions { GZip, Deflate, None }
上面的代码使用正则表达式替换字符串,你可以修改那些正则表达式来满足你的需求. 我们同时使用了GZipStream与DeflateStream实现了压缩. 好的,接下来与HttpModule结合:
- /// <summary>
- /// CompressWhitespaceModule
- /// </summary>
- public class CompressWhitespaceModule : IHttpModule
- {
- #region IHttpModule Members
- /// <summary>
- /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
- /// </summary>
- public void Dispose()
- {
- // Nothing to dispose;
- }
- /// <summary>
- /// Initializes a module and prepares it to handle requests.
- /// </summary>
- /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param>
- public void Init(HttpApplication context)
- {
- context.BeginRequest += new EventHandler(context_BeginRequest);
- }
- /// <summary>
- /// Handles the BeginRequest event of the context control.
- /// </summary>
- /// <param name="sender">The source of the event.</param>
- /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
- void context_BeginRequest(object sender, EventArgs e)
- {
- HttpApplication app = sender as HttpApplication;
- if (app.Request.RawUrl.Contains(".aspx"))
- {
- HttpContext context = app.Context;
- HttpRequest request = context.Request;
- string acceptEncoding = request.Headers["Accept-Encoding"];
- HttpResponse response = context.Response;
- if (!string.IsNullOrEmpty(acceptEncoding))
- {
- acceptEncoding = acceptEncoding.ToUpperInvariant();
- if (acceptEncoding.Contains("GZIP"))
- {
- response.Filter = new CompressWhitespaceFilter(context.Response.Filter, CompressOptions.GZip);
- response.AppendHeader("Content-encoding", "gzip");
- }
- else if (acceptEncoding.Contains("DEFLATE"))
- {
- response.Filter = new CompressWhitespaceFilter(context.Response.Filter, CompressOptions.Deflate);
- response.AppendHeader("Content-encoding", "deflate");
- }
- }
- response.Cache.VaryByHeaders["Accept-Encoding"] = true;
- }
- }
- #endregion
- }
/// <summary> /// CompressWhitespaceModule /// </summary> public class CompressWhitespaceModule : IHttpModule { #region IHttpModule Members /// <summary> /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>. /// </summary> public void Dispose() { // Nothing to dispose; } /// <summary> /// Initializes a module and prepares it to handle requests. /// </summary> /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param> public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(context_BeginRequest); } /// <summary> /// Handles the BeginRequest event of the context control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param> void context_BeginRequest(object sender, EventArgs e) { HttpApplication app = sender as HttpApplication; if (app.Request.RawUrl.Contains(".aspx")) { HttpContext context = app.Context; HttpRequest request = context.Request; string acceptEncoding = request.Headers["Accept-Encoding"]; HttpResponse response = context.Response; if (!string.IsNullOrEmpty(acceptEncoding)) { acceptEncoding = acceptEncoding.ToUpperInvariant(); if (acceptEncoding.Contains("GZIP")) { response.Filter = new CompressWhitespaceFilter(context.Response.Filter, CompressOptions.GZip); response.AppendHeader("Content-encoding", "gzip"); } else if (acceptEncoding.Contains("DEFLATE")) { response.Filter = new CompressWhitespaceFilter(context.Response.Filter, CompressOptions.Deflate); response.AppendHeader("Content-encoding", "deflate"); } } response.Cache.VaryByHeaders["Accept-Encoding"] = true; } } #endregion }
HttpApplication.BeginRequest 事件是 在 ASP.NET 响应请求时作为 HTTP 执行管线链中的第一个事件发生。 在WEB.CONFIG中你还需要配置:
- <httpModules>
- <add name="CompressWhitespaceModule" type="MyWeb.CompressWhitespaceModule" />
- </httpModules>
<httpModules> <add name="CompressWhitespaceModule" type="MyWeb.CompressWhitespaceModule" /> </httpModules>
我们来看一下效果。 没有使用压缩时为4.8K
使用压缩后,为1.6K
很简单,你可以按需求来增加更多的功能. 希望对您开发有帮助。