ASP.NET页面实时进行GZIP压缩优化

本文主要讲述ASP.NET网站开发者,给网站增加GZIP压缩模块,提高网页传输速度,由此增加页面显示速度。

什么是网页GZIP压缩?
这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中的网站时,服务器中的这个功能就将网页内容压缩后传输到来访的电脑浏览器中显示出来.一般对纯文本内容可压缩到原大小的40%.这样传输就快了,效果就是你点击网址后会很快的显示出来.当然这也会增加服务器的负载.
一般服务器中都安装有这个功能模块的.

CompressionModule类,主要是开启GZIP压缩功能。

 

 
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.IO;
using System.IO.Compression;

namespace Compression
{
public class CompressionModule : IHttpModule
{
void IHttpModule.Dispose()
{ }

void IHttpModule.Init(HttpApplication context)
{
context.PreRequestHandlerExecute
+= new EventHandler(context_PostReleaseRequestState);
}

void context_PostReleaseRequestState( object sender, EventArgs e)
{
HttpApplication app
= (HttpApplication)sender;
if (app.Context.CurrentHandler is System.Web.UI.Page && app.Request[ " HTTP_X_MICROSOFTAJAX " ] == null )
{
if (IsEncodingAccepted(GZIP))
{
app.Response.Filter
= new GZipStream(app.Response.Filter, CompressionMode.Compress);
SetEncoding(GZIP);
}
else if (IsEncodingAccepted(DEFLATE))
{
app.Response.Filter
= new DeflateStream(app.Response.Filter, CompressionMode.Compress);
SetEncoding(DEFLATE);
}
}
}

private const string GZIP = " gzip " ;
private const string DEFLATE = " deflate " ;

private static bool IsEncodingAccepted( string encoding)
{
HttpContext context
= HttpContext.Current;
return context.Request.Headers[ " Accept-encoding " ] != null && context.Request.Headers[ " Accept-encoding " ].Contains(encoding);
}

private static void SetEncoding( string encoding)
{
HttpContext.Current.Response.AppendHeader(
" Content-encoding " , encoding);
}
}
}

 

 

PageBase类,是为了让继承PageBase的页面的head里出现的JS,CSS文件,通过r.aspx输出,由此来启用gzip压缩。

 

 
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace Compression
{
public class PageBase : Page
{
protected override void OnLoad(EventArgs e)
{
base .OnLoad(e);

CompressJs();
CompressCss();
}
public virtual void CompressJs()
{
foreach (Control control in Page.Header.Controls)
{
LiteralControl c
= control as LiteralControl;
if (c != null && c.Text.Trim().StartsWith( " <script " , StringComparison.OrdinalIgnoreCase) && ! c.Text.Contains( " http:// " ))
{
string text = c.Text.Trim();
int i = text.IndexOf( " src=/" " );
c.Text
= text.Insert(i + 5 , " /r.aspx?name= " );
}
}
}

public virtual void CompressCss()
{
foreach (Control control in Page.Header.Controls)
{
HtmlControl c
= control as HtmlControl;
if (c != null && c.Attributes[ " type " ] != null && c.Attributes[ " type " ].Equals( " text/css " , StringComparison.OrdinalIgnoreCase))
{
if ( ! c.Attributes[ " href " ].StartsWith( " http:// " ))
{
c.Attributes[
" href " ] = " /r.aspx?name= " + c.Attributes[ " href " ];
c.EnableViewState
= false ;
}
}
}
}
}
}

 

 

r.aspx后台代码,读取对应的JS,CSS文件,并且缓存到服务器内存上,提高脚本文件和样式文件的读取速度。

 

 
 
using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Net;

namespace SvnHost
{
public partial class r : Compression.PageBase
{
protected void Page_Load( object sender, EventArgs e)
{
string name = Request.QueryString[ " name " ];
if (name != null && (name.EndsWith( " .js " , StringComparison.OrdinalIgnoreCase) || name.EndsWith( " .css " , StringComparison.OrdinalIgnoreCase)))
{
string text = ( string )Cache[name.ToLower()];

string ContentType = SetContentType(name);

if (text == null )
{
using (StreamReader sr = new StreamReader(Server.MapPath(name)))
{
text
= sr.ReadToEnd();
sr.Close();
}
if (ContentType == " text/javascript " )
{
text
= StripWhitespaceJs(text);
}
else if (ContentType == " text/css " )
{
text
= StripWhitespaceCss(text);
}
Cache.Add(name, text,
new System.Web.Caching.CacheDependency(Server.MapPath(name)), DateTime.MaxValue, TimeSpan.Zero, System.Web.Caching.CacheItemPriority.High, null );
}
Response.Clear();
SetHeaders(name, ContentType);
Response.Write(text);
Response.End();
}
}

private string SetContentType( string name)
{
string ContentType = " text/css " ;
if (name.EndsWith( " .js " , StringComparison.OrdinalIgnoreCase))
{
ContentType
= " text/javascript " ;
}
else if (name.EndsWith( " .css " , StringComparison.OrdinalIgnoreCase))
{
ContentType
= " text/css " ;
}
return ContentType;
}

private void SetHeaders( string file, string ContentType)
{
Response.ContentType
= ContentType;
Response.Cache.VaryByHeaders[
" Accept-Encoding " ] = true ;

DateTime date
= DateTime.Now;
if (Cache[file + " date " ] != null )
date
= (DateTime)Cache[file + " date " ];

string etag = " /" " + date.GetHashCode() + " /" " ;
string incomingEtag = Request.Headers[ " If-None-Match " ];

Response.Cache.SetExpires(DateTime.Now.ToUniversalTime().AddDays(
7 ));
Response.Cache.SetCacheability(HttpCacheability.Public);
Response.Cache.SetMaxAge(
new TimeSpan( 7 , 0 , 0 , 0 ));
Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
Response.Cache.SetETag(etag);

if (String.Compare(incomingEtag, etag) == 0 )
{
Response.StatusCode
= ( int )HttpStatusCode.NotModified;
Response.End();
}
}

private string StripWhitespaceJs( string body)
{
string [] lines = body.Split( new string [] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
StringBuilder sb
= new StringBuilder();
foreach ( string line in lines)
{
string s = line.Trim();
if (s.Length > 0 && ! s.StartsWith( " // " ))
sb.AppendLine(s.Trim());
}

body
= sb.ToString();
body
= Regex.Replace(body, @" ^[/s]+|[ /f/r/t/v]+$ " , String.Empty);
body
= Regex.Replace(body, @" ([+-])/n/1 " , " $1 $1 " );
body
= Regex.Replace(body, @" ([^+-][+-])/n " , " $1 " );
body
= Regex.Replace(body, @" ([^+]) ?(/+) " , " $1$2 " );
body
= Regex.Replace(body, @" (/+) ?([^+]) " , " $1$2 " );
body
= Regex.Replace(body, @" ([^-]) ?(/-) " , " $1$2 " );
body
= Regex.Replace(body, @" (/-) ?([^-]) " , " $1$2 " );
body
= Regex.Replace(body, @" /n([{}()[/],<>/*%&|^!~?:=.;+-]) " , " $1 " );
body
= Regex.Replace(body, @" (/W(if|while|for)/([^{]*?/))/n " , " $1 " );
body
= Regex.Replace(body, @" (/W(if|while|for)/([^{]*?/))((if|while|for)/([^{]*?/))/n " , " $1$3 " );
body
= Regex.Replace(body, @" ([;}]else)/n " , " $1 " );
body
= Regex.Replace(body, @" (?<=[>])/s{2,}(?=[<])|(?<=[>])/s{2,}(?=&nbsp;)|(?<=&ndsp;)/s{2,}(?=[<]) " , String.Empty);

return body;
}

private string StripWhitespaceCss( string body)
{
body
= body.Replace( " " , String.Empty);
body
= body.Replace(Environment.NewLine, String.Empty);
body
= body.Replace( " /t " , string .Empty);
body
= body.Replace( " { " , " { " );
body
= body.Replace( " : " , " : " );
body
= body.Replace( " : " , " : " );
body
= body.Replace( " , " , " , " );
body
= body.Replace( " ; " , " ; " );
body
= body.Replace( " ;} " , " } " );
// body = Regex.Replace(body, @"//*[^/*]*/*+([^//*]*/*+)*/", "$1");
body = Regex.Replace(body, @" (?<=[>])/s{2,}(?=[<])|(?<=[>])/s{2,}(?=&nbsp;)|(?<=&ndsp;)/s{2,}(?=[<]) " , String.Empty);

return body;
}
}
} 详细下载地址:asp.net网站使用GZIP压缩源代码

text/html; charset=utf-8 : 1143 bytes, gzip compressed to 962 bytes ( 15.8 % saving )
text/css; charset=utf-8 : 4435 bytes, gzip compressed to 1487 bytes ( 66.5 % saving )
text/javascript; charset=utf-8 : 125592 bytes, gzip compressed to 32646 bytes ( 74 % saving )

可以看到压缩比例高达:74%,还不包括发送以前替换的空格等不可见字符,另外由于放到内存中缓存了,所以性能提升理论上说应该是非常的可观。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值