压缩响应和 HTML 空白字符移除器






4.85/5 (24投票s)
使用 GZipStream 或 DeflateStream 压缩你的 HTML 输出,在可用时将其包含在响应中。 添加了一个新的类 WhiteSpaceFilter,用于移除 HTML 中的空白字符。
压缩
显而易见,我们需要在将响应传递给客户端时对其进行压缩。 压缩的请求和响应总是能提高网站的性能。 如今,几乎 99% 的浏览器都支持 Gzip 或 Deflate 压缩,甚至两者都支持。 因此,如果我们可以检查请求头中是否存在“Accept-Encoding”头,并向客户端返回压缩的响应,那么我们就提高了网站的性能。 请查看下面的代码:
public static void doCompression()
{
HttpContext context = HttpContext.Current;
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 GZipStream(context.Response.Filter,
CompressionMode.Compress);
response.AppendHeader("Content-encoding", "gzip");
}
else if (acceptEncoding.Contains("DEFLATE"))
{
response.Filter = new DeflateStream(context.Response.Filter,
CompressionMode.Compress);
response.AppendHeader("Content-encoding", "deflate");
}
}
response.Cache.VaryByHeaders["Accept-Encoding"] = true;
}
在这里,我们检查请求头是否包含“Accept-Encoding”。 根据它支持的编码,我们使用 GZipStream
/ DeflateStream
过滤响应,这些类在 System.IO.Compression
命名空间中可用。 因此,响应将被压缩。 但是,这并不能帮助客户端正确渲染你的页面。 你需要将 Content-Encoding 头添加到响应中,以便客户端能够正确解压缩响应。 我们添加一个 Response 头“Accept-Encoding”,以便请求也使用相同的编码发送数据。
你还可以移除 HTML 中的空白字符来缩小响应。 使用这个类:
public enum CompressOptions
{
GZip,
Deflate,
None
}
public class WhitespaceFilter : Stream
{
private GZipStream _contentGZip;
private DeflateStream _content_Deflate;
private Stream _content;
private CompressOptions _options;
public WhitespaceFilter(Stream content, CompressOptions options)
{
if (options == CompressOptions.GZip)
{
this._contentGZip = new GZipStream(content, CompressionMode.Compress);
this._content = this._contentGZip;
}
else if (options == CompressOptions.Deflate)
{
this._content_Deflate = new DeflateStream(content,
CompressionMode.Compress);
this._content = this._content_Deflate;
}
else
{
this._content = content;
}
this._options = options;
}
public override bool CanRead
{
get { return this._content.CanRead; }
}
public override bool CanSeek
{
get { return this._content.CanSeek; }
}
public override bool CanWrite
{
get { return this._content.CanWrite; }
}
public override void Flush()
{
this._content.Flush();
}
public override long Length
{
get { return this._content.Length; }
}
public override long Position
{
get
{
return this._content.Position;
}
set
{
this._content.Position = value;
}
}
public override int Read(byte[] buffer, int offset, int count)
{
return this._content.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return this._content.Seek(offset, origin);
}
public override void SetLength(long value)
{
this._content.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 s = System.Text.Encoding.UTF8.GetString(data);
s = Regex.Replace(s, "^\\s*",string.Empty, RegexOptions.Compiled |
RegexOptions.Multiline);
s = Regex.Replace(s, "\\r\\n", string.Empty, RegexOptions.Compiled |
RegexOptions.Multiline);
s = Regex.Replace(s, "<!--*.*?-->", string.Empty, RegexOptions.Compiled |
RegexOptions.Multiline);
byte[] outdata = System.Text.Encoding.UTF8.GetBytes(s);
this._content.Write(outdata, 0, outdata.GetLength(0));
}
}
要使用它,只需编写:
internal void Compress()
{
HttpContext context = HttpContext.Current;
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 GZipStream(context.Response.Filter,
//CompressionMode.Compress);
response.Filter = new WhitespaceFilter(context.Response.Filter,
CompressOptions.GZip);
response.AppendHeader("Content-encoding", "gzip");
}
else if (acceptEncoding.Contains("DEFLATE"))
{
//response.Filter = new DeflateStream(context.Response.Filter,
//CompressionMode.Compress);
response.Filter = new WhitespaceFilter(context.Response.Filter,
CompressOptions.Deflate);
response.AppendHeader("Content-encoding", "deflate");
}
}
response.Cache.VaryByHeaders["Accept-Encoding"] = true;
}
注意:我使用的正则表达式将移除 HTML 中的额外空格、换行符和注释。 因此,它将减小 HTML 的大小。 另外,在使用它在生产环境中之前,请检查它的工作方式,因为你需要根据你的需要更改正则表达式。