Eu tive este "problema" alguns dias atrás e necessitava urgentemente compactar os arquivos estáticos do jQuery UI para garantir performance no carregamento das páginas.
A minha solução foi bastante simples. Pensei em obter os arquivos estáticos e compactá-los em runtime utilizando o algoritmo do GZip (classe GZipStream) e passar para o browser este conteúdo compactado identificando que este era um conteúdo com o encoding do tipo GZip.
Para implementar esta solução, primeiro criei um arquivo do tipo Generic Handler (ziparArquivo.ashx), e em seguida alterei o método ProcessRequest para que realizasse o que eu estava imaginando, conforme código comentado:
public void ProcessRequest(HttpContext context)
{
//Verifico a existência dos parâmetros
if (context.Request["arquivo"] != null && context.Request["tipo"] != null)
{
string arquivo = context.Request["arquivo"].ToString();
string tipo = context.Request["tipo"].ToString();
context.Response.ContentType = tipo.Equals(string.Empty) ? "text/plain" : tipo;
//Informo ao browser que o cache desta chamada será de 5 meses,
//para que não necessite carregar toda hora que for solicitado.
context.Response.Cache.SetExpires(DateTime.Now.AddMonths(5));
//Obtenho os bytes do conteúdo do arquivo
byte[] bufferArquivo = File.ReadAllBytes(context.Server.MapPath(arquivo));
//Verifico se o browser suporta descompactar arquivos em formato GZip
if (context.Request.Headers["Accept-Encoding"] != null && context.Request.Headers["Accept-Encoding"].ToString().ToLower().Contains("gzip"))
{
//Informo ao browser que o conteúdo deste arquivo é do tipo GZip
context.Response.AppendHeader("Content-Encoding", "gzip");
//Verifico se o arquivo já está no Cache do ASP.NET
if (context.Cache[arquivo] == null)
{
//Crio um MemoryStream para armazenar o conteúdo compactado.
using (MemoryStream msArquivo = new MemoryStream())
{
//Utilizo a classe GZipStream para compactar o arquivo solicitado.
using (GZipStream streamGzip = new GZipStream(msArquivo, CompressionMode.Compress))
{
//Escrevo no objeto do GZip o conteúdo resgatado do arquivo solicitado.
streamGzip.Write(bufferArquivo, 0, (int)bufferArquivo.Length);
streamGzip.Close();
}
//Resgato o conteúdo do arquivo, mas agora em seu formato compactado.
bufferArquivo = msArquivo.ToArray();
//Adiciono o conteúdo do arquivo no Cache do ASP.NET para uma chamada posterior.
context.Cache.Add(arquivo, bufferArquivo, null, DateTime.Now.AddMonths(5), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
msArquivo.Close();
}
}
else
{
//Se o arquivo já estiver no Cache do ASP.NET, somente recupero o conteúdo.
bufferArquivo = (byte[])context.Cache[arquivo];
}
}
//Efetuo um Write no ASHX para que o conteúdo do arquivo compactado ou não seja processado.
context.Response.OutputStream.Write(bufferArquivo, 0, (int)bufferArquivo.Length);
}
}
Após criar o ASHX, alterei o código html da MasterPage para que efetuasse a chamada a este novo ASHX, passando por parâmetro o nome dos arquivos estáticos.
<head>
<title>Página</title>
<link href="ziparArquivo.ashx?arquivo=jquery-ui-1.8.16.custom.css&tipo=text/css" rel="stylesheet" type="text/css" />
<script src="ziparArquivo.ashx?arquivo=jquery-1.7.1.min.js&tipo=application/x-javascript" type="text/javascript"></script>
<script src="ziparArquivo.ashx?arquivo=jquery-ui-1.8.16.custom.min.js&tipo=application/x-javascript" type="text/javascript"></script>
</head>
0 comentários:
Postar um comentário