A saída da maioria das páginas ASP.NET é na forma de texto. Nos termos do HTTP, o tipo de conteúdo é chamado de “text/html”. O texto recebido pelo navegador do cliente, a partir da página ASP.NET em um servidor Web IIS, é então processado no navegador. Uma vez que esta comunicação se realiza através da Internet, que consome largura de banda. Por exemplo, uma página ASP.NET de 40 KB terá exatamente 40 KB de largura de banda da rede (além da largura de banda para os cabeçalhos enviados e recebidos pelo navegador do cliente). Para otimizar e melhorar o desempenho desse ciclo de comunicação, HTTP e compressão Gzip é usado. A compressão HTTP permitirá que 40 KB sejam compactados usando Gzip para uns 12-15 KB, poupando 25-28 KB de largura de banda da rede. Agora, considere as implicações dessa poupança de largura de banda da rede ao longo de centenas de milhares de pedidos tratados por cada dia pelo servidor IIS. Isto pode ser grande? Não é? Adicione a isso o fato de que seu site irá carregar mais rapidamente e, assim, melhorar a experiência do usuário e a percepção do seu site.
Como habilitar a compactação HTTP em nossas páginas ASP.NET?
A primeira coisa que você deve saber é que a compressão HTTP pode ser feita usando o Gzip ou Deflate. Para usar a compactação HTTP em nossas páginas ASP.NET sem editar cada uma das páginas, vamos fazer uso de dos eventos do ciclo de vida no arquivo Global.asax.
Um arquivo Global.asax é colocado na pasta do seu aplicativo ASP.NET. Ele pode conter métodos para lidar com eventos de ciclo de vida. Os nomes e detalhes de todos os eventos de que pode manipular no arquivo Global.asax está além do escopo deste tutorial. Mas um evento que irá tratar e onde vamos inserir o nosso código é o PreRequestHandlerExecute. Ocorre imediatamente antes do ASP.NET começar a executar um manipulador de eventos. A assinatura do método completo para lidar com este evento é apresentado abaixo:
void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
…
}
Nota: A convenção de nomenclatura usada pelo ASP.NET para vincular eventos de aplicação como PreRequestHandlerExecute com manipuladores de eventos reais é usar o nome do objeto que dispara o evento, neste caso Application, com o sublinhado (_ personagem) e, finalmente, vem o evento próprio nome, que no nosso caso é PreRequestHandlerExecute.
Por que o nosso padrão de HTTP Compression Method será Deflate?
Nós vamos usar a compressão Deflate HTTP por padrão, pois oferece uma compressão e descompressão mais rápida. Para mais detalhes, leia este artigo: Gzip vs Deflate: Which is the faster HTTP compression method?
Vamos direto ao código:
<%@ Application %>
<%@ Import Namespace="System.IO" %>
<%@ Import Namespace="System.IO.Compression" %>
<script runat="server">
void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
HttpApplication app = sender as HttpApplication;
String acceptEncoding = app.Request.Headers["Accept-Encoding"];
Stream prevUncompressedStream = app.Response.Filter;
if (!(app.Context.CurrentHandler is Page ||
app.Context.CurrentHandler.GetType().Name == "SyncSessionlessHandler") ||
app.Request["HTTP_X_MICROSOFTAJAX"] != null)
return;
if (acceptEncoding == null || acceptEncoding.Length == 0)
return;
acceptEncoding = acceptEncoding.ToLower();
if (acceptEncoding.Contains("deflate") || acceptEncoding == "*")
{ // defalte
app.Response.Filter = new DeflateStream(prevUncompressedStream,
CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "deflate");
} else if (acceptEncoding.Contains("gzip"))
{ // gzip
app.Response.Filter = new GZipStream(prevUncompressedStream,
CompressionMode.Compress);
app.Response.AppendHeader("Content-Encoding", "gzip");
}
}
</script>
Explicação
Pessoal, o código acima é tudo o que é necessário para habilitar a compactação HTTP em suas páginas ASP.NET. Vamos agora concentrar-se sobre os detalhes do código apresentado acima.
A primeira coisa que fazemos é para dizer ao compilador que o código ASP.NET vai ser na linguagem, C #.
Em seguida, importar os namespaces que o nosso código irá utilizar. Lembre-se, o GZipStream e classes DeflateStream são novos no ASP.NET 2.0 e que estão presentes no namespace System.IO.Compression.
Em seguida, nós declaramos o método que manipulará o evento o ciclo de vida PreRequestHandlerExecute. Como explicado anteriormente, esse evento ocorre antes que ASP.NET começe a executar um manipulador de eventos.
void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
…
}
Em seguida, obtemos do objeto remetente, usando a palavra-chave, em uma variável do tipo HttpApplication, porque este é o objeto que acionou o evento para começar. Se o navegador cliente suporta os fluxos de conteúdo dos tipos, gzip e deflate, o valor deste cabeçalho irá contê-los. Uma referência ao atual fluxo de saída descompactado objeto usado pelo ASP.NET para enviar o texto puro (ou binários) de saída para o navegador do cliente é guardada no objeto prevUncompressedStream.
Nós tentamos garantir que o recurso solicitado é uma página ASP.NET válida ou um Web Service. Se não for, então não fazemos nada. Além disso, foram verificados “HTTP_X_MICROSOFTAJAX item” na coleção HttpRequest. Este item está freqüentemente presente quando se utiliza AJAX em páginas ASP.NET. Quando o conteúdo AJAX é comprimido, a página pode acionar exceções. Assim, não comprimir a página se AJAX está sendo usado.
Nota: Agora você pode ativar a compactação HTTP, não apenas em suas páginas web ASP.NET, mas em seus serviços web ASP.NET. Tudo que você tem a fazer é procurar também o nome do tipo de propriedade CurrentHandler e combiná-lo com “SyncSessionlessHandler”.
Finalmente, verifique se o navegador do cliente não envia o “Accept-Encoding”, ou se ele mandou, mas seu valor está vazio, significa que o navegador do cliente não pode processar o conteúdo compactado. Neste caso, basta retornar a este método e não fazer nada.
HttpApplication app = sender as HttpApplication;
string acceptEncoding = app.Request.Headers["Accept-Encoding"];
Stream prevUncompressedStream = app.Response.Filter;
if (!(app.Context.CurrentHandler is Page ||
app.Context.CurrentHandler.GetType().Name == “SyncSessionlessHandler”) ||
app.Request["HTTP_X_MICROSOFTAJAX"] != null)
return;
if (acceptEncoding == null || acceptEncoding.Length == 0)
return;
Em seguida, defina o caso de todos os personagens no valor do cabeçalho acceptEncoding estejam minúsculas. Nós fazemos isso para que quando tentamos comparar a presença de seqüências como “gzip” e “deflate” a variável acceptEncoding, valores como o ” GZIP “, ” gZiP “, e ” Gzip” será interpretado como uma mesma coisa.
acceptEncoding = acceptEncoding.ToLower();
Por fim, buscamos o cabeçalho acceptEncoding para o valor “deflate”. Se estiver presente, criamos um novo objeto DeflateStream e defina a propriedade Response.Filter a este valor. Isto significa que todas as chamadas para Response.Write () no código ASP.NET realmente acessam o objeto DeflateStream. Em seguida, nós também definimos a saída de cabeçalho “Content-Encoding”, com o valor de “deflate” para indicar ao navegador do cliente que a codificação de conteúdo que vai ser Deflate comprimido para que ele possa descompactá-lo no client-side.
Por último, se o cliente navegador não suporta stream ” deflate ” mas apóia o “gzip” stream, fazemos uso de GZipStream no local do objeto DeflateStream.
if (acceptEncoding.Contains(“deflate”) || acceptEncoding == “*”)
{
// defalte
app.Response.Filter = new DeflateStream(prevUncompressedStream,
CompressionMode.Compress);
app.Response.AppendHeader(“Content-Encoding”, “deflate”);
} else if (acceptEncoding.Contains(“gzip”))
{
// gzip
app.Response.Filter = new GZipStream(prevUncompressedStream,
CompressionMode.Compress);
app.Response.AppendHeader(“Content-Encoding”, “gzip”);
}
Isso é tudo pessoal. Agora faça as alterações descritas acima e acesse uma página ASP.NET no seu site. Você pode verificar se uma página ASP.NET está sendo comprimida ou não usando uma versão online gratuita, aqui.