javascriptを圧縮するために、私はjscompressを使用しました 。私のニーズに合わせて少し変更しました。
起こったことは次のとおりです。
<%@ WebHandler Language= "C#" Class= "StaticFilesCombiner" %>
using System;
using System.Net;
using System.IO;
using System.IO.Compression;
using System.Text;
using System.Web;
using JSCompress;
public class StaticFilesCombiner: IHttpHandler {
private readonly static TimeSpan CACHE_DURATION = TimeSpan .FromDays(30);
private const string JQuery = "jquery-1.2.6.min.js" ;
public void ProcessRequest ( HttpContext context) {
HttpRequest request = context.Request;
// , contentType .
//
string setName = request[ "s" ] ?? string .Empty;
string contentType = request[ "t" ] ?? string .Empty;
string version = request[ "v" ] ?? string .Empty;
bool isCompressed = CanGZip(context.Request);
bool isJS = contentType.Contains( "java" );
UTF8Encoding encoding = new UTF8Encoding( false );
if (!WriteFromCache(context, setName, version, isCompressed, contentType))
{
using (MemoryStream memoryStream = new MemoryStream(5000))
{
using ( Stream writer = isCompressed ?
( Stream )( new GZipStream(memoryStream, CompressionMode.Compress)) :
memoryStream)
{
// <appSettings>
string setDefinition =
System.Configuration. ConfigurationManager .AppSettings[setName] ?? "" ;
string [] fileNames = setDefinition.Split( new [] { ',' },
StringSplitOptions.RemoveEmptyEntries);
foreach ( string fileName in fileNames)
{
byte [] fileBytes = GetFileBytes(context, fileName.Trim(), encoding, isJS);
writer.Write(fileBytes, 0, fileBytes.Length);
}
writer.Close();
}
byte [] responseBytes = memoryStream.ToArray();
context.Cache.Insert(GetCacheKey(setName, version, isCompressed),
responseBytes, null , System.Web.Caching.Cache.NoAbsoluteExpiration,
CACHE_DURATION);
WriteBytes(responseBytes, context, isCompressed, contentType);
}
}
}
/// <summary>
/// CSS.
/// </summary>
public static string MinifyCss( string body)
{
StringBuilder builder = new StringBuilder (body);
builder = builder.Replace( " " , string .Empty);
builder = builder.Replace(Environment.NewLine, string .Empty);
builder = builder.Replace( "\t" , string .Empty);
builder = builder.Replace( " {" , "{" );
builder = builder.Replace( " :" , ":" );
builder = builder.Replace( ": " , ":" );
builder = builder.Replace( ", " , "," );
builder = builder.Replace( "; " , ";" );
builder = builder.Replace( ";}" , "}" );
return builder.ToString();
}
/// <summary>
/// js.
/// </summary>
private static string MinifyJS( string notCompressedString, string virtualPath)
{
// JQuery, .
if (virtualPath.Contains(JQuery))
{
return notCompressedString;
}
JSCompressor jsCOmpressor = new JSCompressor( true )
{
CompressVariableNames = false ,
LineFeedRemoval = true
};
return jsCOmpressor.Compress(notCompressedString);
}
private static byte [] GetFileBytes( HttpContext context, string virtualPath, Encoding encoding, bool isJS)
{
string compressedString;
string notCompressedString;
if (virtualPath.StartsWith( "http://" , StringComparison.InvariantCultureIgnoreCase))
{
using (WebClient client = new WebClient())
{
notCompressedString = client.DownloadString(virtualPath);
compressedString = isJS ? MinifyJS(notCompressedString, virtualPath) : MinifyCss(notCompressedString);
return encoding.GetBytes(compressedString);
}
}
string physicalPath = context.Server.MapPath(virtualPath);
notCompressedString = File .ReadAllText(physicalPath);
compressedString = isJS ? MinifyJS(notCompressedString, physicalPath) : MinifyCss(notCompressedString);
return encoding.GetBytes(compressedString);
}
private static bool WriteFromCache( HttpContext context, string setName, string version,
bool isCompressed, string contentType)
{
byte [] responseBytes = context.Cache[GetCacheKey(setName, version, isCompressed)] as byte [];
if ( null == responseBytes || 0 == responseBytes.Length) return false ;
WriteBytes(responseBytes, context, isCompressed, contentType);
return true ;
}
private static void WriteBytes( byte [] bytes, HttpContext context,
bool isCompressed, string contentType)
{
HttpResponse response = context.Response;
response.AppendHeader( "Content-Length" , bytes.Length.ToString());
response.ContentType = contentType;
if (isCompressed)
response.AppendHeader( "Content-Encoding" , "gzip" );
context.Response.Cache.SetCacheability(HttpCacheability.Public);
context.Response.Cache.SetExpires( DateTime .Now.Add(CACHE_DURATION));
context.Response.Cache.SetMaxAge(CACHE_DURATION);
context.Response.Cache.AppendCacheExtension( "must-revalidate, proxy-revalidate" );
response.OutputStream.Write(bytes, 0, bytes.Length);
response.Flush();
}
private static bool CanGZip(HttpRequest request)
{
string acceptEncoding = request.Headers[ "Accept-Encoding" ];
if (! string .IsNullOrEmpty(acceptEncoding) &&
(acceptEncoding.Contains( "gzip" ) || acceptEncoding.Contains( "deflate" )))
return true ;
return false ;
}
private static string GetCacheKey( string setName, string version, bool isCompressed)
{
return "StaticFilesCombiner." + setName + "." + version + "." + isCompressed;
}
public bool IsReusable
{
get
{
return true ;
}
}
}
* This source code was highlighted with Source Code Highlighter .
それを使用するには、web.configに数行を追加するだけです:
< appSettings >
< add key ="Main_Css" value ="~/styles/styles.css" />
< add key ="Set_Css" value ="~/styles/Compare.css,~/styles/anycss.css,~/styles/ImageGallery.css,~/styles/styles.css,~/styles/thickbox.css" />
< add key ="Set_Javascript" value ="~/js/jquery-1.2.6.min.js,~/js/basket.js,~/js/jquery.galleria.js,~/js/thickbox-compressed.js" />
< add key ="SiteName" value ="stirka.spb.ru" />
</ appSettings >
* This source code was highlighted with Source Code Highlighter .
実際、これらは結合と圧縮のためのファイルのセットです。
そして、使用自体:
< link type ="text/css" rel ="Stylesheet" href ="StaticFilesCombiner.ashx?s=Main_Css&t=text/css&v=13" />
* This source code was highlighted with Source Code Highlighter .