Fundamentos de la Compresión HTTP en ASP.NET Core
La compresión de respuestas representa una estrategia crucial para minimizar el volumen de datos transmitidos entre servidor y clientes, impactando directamente en la velocidad de carga de aplicaciones web y en la optimización del ancho de banda consumido.
Contextos de Aplicación del Middleware de Compresión
El middleware integrado en ASP.NET Core resulta particularmente valioso cuando no se dispone de soluciones de compresión a nivel de servidor web. Las plataformas como IIS, Apache y Nginx ofrecen módulos nativos de compresión que generalmente superan en eficiencia al middleware, sin embargo, existen escenarios específicos donde su implementación es necesaria:
- Servidores autónomos: Al utilizar Http.sys o Kestrel sin un proxy inverso
- Entornos restringidos: Cuando no es posible configurar módulos de servidor
- Desarrollo local: Para pruebas de rendimiento sin infraestructura completa
Configuración Básica del Middleware
La activcaión requiere registrar el servicio en el contenedor de dependencias y posteriormente incorporarlo a la canalera de procesamiento de solicitudes.
public void ConfigurarServicios(IServiceCollection servicios)
{
servicios.AddResponseCompression();
servicios.AddControllersWithViews();
}
public void ConfigurarAplicacion(IApplicationBuilder aplicacion, IWebHostEnvironment ambiente)
{
if (ambiente.IsDevelopment())
{
aplicacion.UseDeveloperExceptionPage();
}
else
{
aplicacion.UseExceptionHandler("/Home/Error");
aplicacion.UseHsts();
}
aplicacion.UseResponseCompression();
aplicacion.UseStaticFiles();
aplicacion.UseRouting();
aplicacion.UseAuthorization();
aplicacion.UseEndpoints(puntosExtremos =>
{
puntosExtremos.MapDefaultControllerRoute();
});
}
Tipos MIME Compresibles por Defecto
El middleware incluye una colección predefinida de tipos de contenido susceptibles a compresión:
- application/javascript
- application/json
- application/xml
- text/css
- text/html
- text/plain
- text/xml
Algoritmos de Compresión: Brotli y Gzip
El sistema utiliza Brotli como algoritmo preferencial por su superior relación de compresión. Este método, desarrollado por Google, combina una variante moderna de LZ77 con codificación Huffman y modelado de contexto de segundo orrden. Cuando el cliente no soporta Brotli, el sistema recurre automáticamente a Gzip.
public void ConfigurarServicios(IServiceCollection servicios)
{
servicios.AddResponseCompression(opciones => {
opciones.Providers.Add<BrotliCompressionProvider>();
opciones.Providers.Add<GzipCompressionProvider>();
});
servicios.AddRazorPages();
}
Extensión de Tipos MIME Personalizados
Para incluir formatos adicionales no contemplados en la lista predeterminada, se puede extender la colección mediante concatenación:
public void ConfigurarServicios(IServiceCollection servicios)
{
servicios.AddResponseCompression(opciones => {
opciones.Providers.Add<BrotliCompressionProvider>();
opciones.Providers.Add<GzipCompressionProvider>();
opciones.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "image/svg+xml", "application/wasm", "font/woff2" });
});
}
Niveles de Compresión Disponibles
| Nivel | Descripción |
|---|---|
CompressionLevel.Fastest |
Prioriza la velocidad de procesamiento sobre la tasa de compresión |
CompressionLevel.Optimal |
Busca la máxima compresión aunque incremente el tiempo de CPU |
CompressionLevel.NoCompression |
Deshabilita la compresión para el proveedor especificado |
Configuración específica del nivel:
public void ConfigurarServicios(IServiceCollection servicios)
{
servicios.AddResponseCompression();
servicios.Configure<BrotliCompressionProviderOptions>(opciones => {
opciones.Level = CompressionLevel.Optimal;
});
servicios.Configure<GzipCompressionProviderOptions>(opciones => {
opciones.Level = CompressionLevel.Fastest;
});
}
Implicaciones de Seguridad en HTTPS
La compresión sobre conexiones seguras está deshabilitada por defecto debido a vulnerabilidades como los ataques CRIME y BREACH. Solo debe activares mediante EnableForHttps después de evaluar los riesgos específicos de la aplicación.
public void ConfigurarServicios(IServiceCollection servicios)
{
servicios.AddResponseCompression(opciones => {
opciones.EnableForHttps = true;
opciones.Providers.Add<GzipCompressionProvider>();
opciones.Providers.Add<BrotliCompressionProvider>();
opciones.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "application/ld+json" });
});
}
Implementación Completa Recomendada
public void ConfigurarServicios(IServiceCollection servicios)
{
servicios.AddResponseCompression(opciones => {
opciones.EnableForHttps = false; // Evaluar seguridad antes de habilitar
opciones.Providers.Add<BrotliCompressionProvider>();
opciones.Providers.Add<GzipCompressionProvider>();
opciones.MimeTypes = ResponseCompressionDefaults.MimeTypes.Concat(
new[] { "image/svg+xml", "application/wasm" });
});
servicios.Configure<BrotliCompressionProviderOptions>(opciones => {
opciones.Level = CompressionLevel.Optimal;
});
servicios.AddControllers();
}
public void ConfigurarAplicacion(IApplicationBuilder aplicacion)
{
aplicacion.UseResponseCompression();
aplicacion.UseStaticFiles();
aplicacion.UseRouting();
aplicacion.UseAuthorization();
aplicacion.UseEndpoints(puntosExtremos => {
puntosExtremos.MapControllers();
});
}