* .jsおよび* .cssファイルを圧縮および圧縮するためのHttpHandler

「写真、スタイルシート、スクリプト、フラッシュなどのページコンポーネントの読み込みにかかる時間のほとんどは...これらのコンポーネントの数を減らすと、クライアントアプリケーションがページをレンダリングする前に必要なサーバーリクエストの数が減ります。」 * .jsおよび* .cssファイルを手動で作成しましたが、最近では少し手始めになり、このプロセスを簡素化することにしました。 これを行うために、私は必要な情報を探してGoogleやテーマフォーラムにあるすべてのものを調べ、それをすべてまとめました。

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 .









All Articles