Ver contenido
Guía Completa de Implementación de Compresión de Texto para Rendimiento Web
Introducción
La compresión de texto puede reducir los tamaños de transferencia en un 60-90%, haciéndola una de las optimizaciones de rendimiento de mayor impacto disponibles. Esta guía proporciona estrategias completas de implementación para diferentes entornos de servidor y plataformas de hosting.
¿Nuevo en compresión? Comienza con nuestra guía para principiantes: 📖 Leer: Compresión de Texto Explicado
Estrategia 1: Compresión a Nivel de Servidor
Configuración de Nginx
# /etc/nginx/nginx.conf o /etc/nginx/conf.d/compression.conf
# Habilitar compresión gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 256;
# Comprimir estos tipos MIME
gzip_types
application/atom+xml
application/geo+json
application/javascript
application/json
application/ld+json
application/manifest+json
application/rdf+xml
application/rss+xml
application/x-javascript
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
# Habilitar Brotli (requiere módulo ngx_brotli)
brotli on;
brotli_comp_level 6;
brotli_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/xhtml+xml
application/xml
font/eot
font/otf
font/ttf
image/svg+xml
text/css
text/javascript
text/plain
text/xml;
Configuración de Apache
# .htaccess o httpd.conf
# Habilitar mod_deflate para gzip
<IfModule mod_deflate.c>
# Forzar compresión para headers Accept-Encoding malformados
<IfModule mod_setenvif.c>
<IfModule mod_headers.c>
SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~telerik|{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding
RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding
</IfModule>
</IfModule>
# Comprimir HTML, CSS, JavaScript, Texto, XML, fuentes
<IfModule mod_filter.c>
AddOutputFilterByType DEFLATE application/atom+xml
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/json
AddOutputFilterByType DEFLATE application/ld+json
AddOutputFilterByType DEFLATE application/manifest+json
AddOutputFilterByType DEFLATE application/rss+xml
AddOutputFilterByType DEFLATE application/xhtml+xml
AddOutputFilterByType DEFLATE application/xml
AddOutputFilterByType DEFLATE font/eot
AddOutputFilterByType DEFLATE font/otf
AddOutputFilterByType DEFLATE font/ttf
AddOutputFilterByType DEFLATE image/svg+xml
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE text/plain
AddOutputFilterByType DEFLATE text/xml
</IfModule>
# No comprimir archivos ya comprimidos
SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|webp|avif|woff2?)$ no-gzip
</IfModule>
# Habilitar mod_brotli (Apache 2.4.26+)
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css
AddOutputFilterByType BROTLI_COMPRESS application/javascript application/json
AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
BrotliCompressionQuality 6
</IfModule>
Configuración de Node.js/Express
// Usando middleware de compresión
const compression = require('compression');
const express = require('express');
const app = express();
// Habilitar compresión para todas las respuestas
app.use(compression({
// Nivel de compresión (0-9, mayor = mejor compresión, más CPU)
level: 6,
// Solo comprimir respuestas mayores a 1KB
threshold: 1024,
// Filtrar qué respuestas comprimir
filter: (req, res) => {
if (req.headers['x-no-compression']) {
return false;
}
return compression.filter(req, res);
}
}));
// Para soporte de Brotli, usar shrink-ray-current
const shrinkRay = require('shrink-ray-current');
app.use(shrinkRay({
brotli: { quality: 6 },
zlib: { level: 6 }
}));
Estrategia 2: Pre-Compresión en Tiempo de Build
Pre-comprimir assets estáticos durante el build ofrece los mejores ratios de compresión ya que puedes usar niveles máximos de compresión sin afectar el tiempo de respuesta.
Configuración de Webpack
// webpack.config.js
const CompressionPlugin = require('compression-webpack-plugin');
const zlib = require('zlib');
module.exports = {
plugins: [
// Generar archivos .gz
new CompressionPlugin({
filename: '[path][base].gz',
algorithm: 'gzip',
test: /\.(js|css|html|svg|json)$/,
threshold: 1024,
minRatio: 0.8,
}),
// Generar archivos .br (Brotli)
new CompressionPlugin({
filename: '[path][base].br',
algorithm: 'brotliCompress',
test: /\.(js|css|html|svg|json)$/,
compressionOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: 11, // Calidad máxima
},
},
threshold: 1024,
minRatio: 0.8,
}),
],
};
Configuración de Vite
// vite.config.js
import { defineConfig } from 'vite';
import viteCompression from 'vite-plugin-compression';
export default defineConfig({
plugins: [
// Compresión Gzip
viteCompression({
algorithm: 'gzip',
ext: '.gz',
threshold: 1024,
}),
// Compresión Brotli
viteCompression({
algorithm: 'brotliCompress',
ext: '.br',
threshold: 1024,
}),
],
});
Nginx Sirviendo Archivos Pre-Comprimidos
# Servir archivos pre-comprimidos si están disponibles
location ~ ^/assets/ {
# Intentar .br primero, luego .gz, luego original
gzip_static on;
brotli_static on;
# Agregar headers apropiados
add_header Vary Accept-Encoding;
# Cachear assets estáticos
expires 1y;
add_header Cache-Control "public, immutable";
}
Estrategia 3: Compresión a Nivel de CDN
La mayoría de los CDNs manejan compresión automáticamente, pero las opciones de configuración varían.
Configuración de Cloudflare
Dashboard de Cloudflare → Speed → Optimization
✅ Auto Minify: HTML, CSS, JavaScript
✅ Brotli: Habilitado (automático para HTTPS)
Nota: Cloudflare automáticamente:
- Sirve Brotli cuando está soportado
- Cae a gzip como respaldo
- Cachea versiones comprimidas
AWS CloudFront
{
"CacheBehavior": {
"Compress": true,
"ViewerProtocolPolicy": "redirect-to-https",
"CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6"
}
}
Vercel/Netlify
Ambos comprimen automáticamente con Brotli/gzip—no se necesita configuración.
Estrategia 4: Optimización de Nivel de Compresión
Entendiendo los Niveles de Compresión
Trade-offs de Nivel de Compresión:
┌─────────────────────────────────────────────────────────────┐
│ Nivel │ Tamaño Gzip │ Tamaño Brotli │ Tiempo CPU │ Mejor Para │
│───────│─────────────│───────────────│────────────│─────────────│
│ 1 │ 100% │ 100% │ Muy Bajo │ APIs tiempo │
│ │ │ │ │ real │
│ 4 │ 92% │ 90% │ Bajo │ Contenido │
│ │ │ │ │ dinámico │
│ 6 │ 88% │ 85% │ Medio │ Balance por │
│ │ │ │ │ defecto │
│ 9 │ 86% │ 80% │ Alto │ Pre- │
│ │ │ │ │ compresión │
│ 11* │ N/A │ 75% │ Muy Alto │ Assets │
│ │ │ │ │ estáticos │
└─────────────────────────────────────────────────────────────┘
* Solo Brotli (niveles 10-11)
Configuraciones Recomendadas
Contenido Dinámico (APIs, HTML renderizado en servidor):
├── Gzip: Nivel 4-6
├── Brotli: Nivel 4-5
└── Justificación: Balance entre compresión y tiempo de respuesta
Assets Estáticos (JS, CSS, pre-construidos):
├── Gzip: Nivel 9
├── Brotli: Nivel 11
└── Justificación: Comprimir una vez, servir muchas veces
Datos en Tiempo Real (WebSocket, streaming):
├── Gzip: Nivel 1-2
├── Brotli: No recomendado
└── Justificación: Minimizar latencia
Estrategia 5: Minificación + Compresión
La minificación y compresión trabajan juntas para máximos ahorros.
Pipeline Combinado
Pipeline de Optimización de Archivo Original:
┌─────────────────────────────────────────────────────────────┐
│ styles.css │
│ ├── Original: 150 KB │
│ ├── Después de Minificación: 95 KB (37% menor) │
│ ├── Después de Gzip: 18 KB (88% menor que original) │
│ └── Después de Brotli: 14 KB (91% menor que original) │
│ │
│ app.js │
│ ├── Original: 500 KB │
│ ├── Después de Minificación: 180 KB (64% menor) │
│ ├── Después de Gzip: 52 KB (90% menor que original) │
│ └── Después de Brotli: 42 KB (92% menor que original) │
└─────────────────────────────────────────────────────────────┘
Por Qué Ambos Importan
// La minificación elimina:
// - Espacios en blanco, comentarios
// - Nombres largos de variables → nombres cortos
// - Código muerto
// La compresión explota:
// - Patrones repetidos (nombres de clase, palabras clave)
// - Secuencias de bytes comunes
// Juntos: Máxima reducción
// El código minificado se comprime mejor porque
// los nombres de variables más cortos se repiten más consistentemente
Estrategia 6: Pruebas y Verificación
Usando curl para Pruebas
# Probar soporte de gzip
curl -H "Accept-Encoding: gzip" -I https://ejemplo.com/styles.css
# Buscar: Content-Encoding: gzip
# Probar soporte de Brotli
curl -H "Accept-Encoding: br" -I https://ejemplo.com/styles.css
# Buscar: Content-Encoding: br
# Probar con ambos
curl -H "Accept-Encoding: gzip, br" -I https://ejemplo.com/styles.css
# Debería retornar br (preferido)
# Obtener tamaño comprimido real
curl -H "Accept-Encoding: gzip" -so /dev/null -w '%{size_download}' https://ejemplo.com/styles.css
Script de Pruebas Automatizado
#!/bin/bash
# compression-check.sh
URL=$1
echo "Probando compresión para: $URL"
echo "---"
# Sin compresión
SIZE_NONE=$(curl -so /dev/null -w '%{size_download}' "$URL")
echo "Sin comprimir: ${SIZE_NONE} bytes"
# Gzip
SIZE_GZIP=$(curl -H "Accept-Encoding: gzip" -so /dev/null -w '%{size_download}' "$URL")
ENCODING_GZIP=$(curl -H "Accept-Encoding: gzip" -sI "$URL" | grep -i content-encoding)
echo "Gzip: ${SIZE_GZIP} bytes (${ENCODING_GZIP})"
# Brotli
SIZE_BR=$(curl -H "Accept-Encoding: br" -so /dev/null -w '%{size_download}' "$URL")
ENCODING_BR=$(curl -H "Accept-Encoding: br" -sI "$URL" | grep -i content-encoding)
echo "Brotli: ${SIZE_BR} bytes (${ENCODING_BR})"
# Calcular ahorros
if [ "$SIZE_NONE" -gt 0 ]; then
SAVINGS_GZIP=$((100 - (SIZE_GZIP * 100 / SIZE_NONE)))
SAVINGS_BR=$((100 - (SIZE_BR * 100 / SIZE_NONE)))
echo "---"
echo "Ahorro Gzip: ${SAVINGS_GZIP}%"
echo "Ahorro Brotli: ${SAVINGS_BR}%"
fi
Midiendo el Impacto
Comparación Antes/Después
ANTES de Optimización de Compresión:
├── Tamaño Total de Transferencia: 1.8 MB
├── TTFB: 850ms
├── FCP: 2.4s
├── Lighthouse Performance: 62
└── Carga de Página (3G): 12.5s
DESPUÉS de Optimización de Compresión:
├── Tamaño Total de Transferencia: 380 KB (↓79%)
├── TTFB: 420ms (↓51%)
├── FCP: 1.1s (↓54%)
├── Lighthouse Performance: 89 (↑27 puntos)
└── Carga de Página (3G): 4.2s (↓66%)
Auditorías de Lighthouse
Verifica estos resultados de auditoría:
- “Enable text compression” - Debería mostrar 0 recursos
- “Properly size images” - Separado de compresión de texto
- “Minify CSS/JavaScript” - Complementa la compresión
Lista de Verificación de Optimización
Antes de desplegar, verifica:
- [ ] Gzip habilitado para todos los tipos MIME basados en texto
- [ ] Brotli habilitado para tráfico HTTPS
- [ ] Pre-compresión para assets estáticos (nivel 9-11)
- [ ] Compresión dinámica en nivel 4-6
- [ ] Imágenes/videos excluidos de compresión
- [ ] Fuentes WOFF2 excluidas (ya comprimidas)
- [ ] Header Vary: Accept-Encoding presente
- [ ] Compresión de CDN habilitada
- [ ] Minificación aplicada antes de compresión
- [ ] Compresión verificada con curl o DevTools
Artículos Relacionados
Continúa optimizando la entrega de tus recursos:
- Compresión de Texto Explicado - Entiende los fundamentos
- Guía de Optimización de TTFB - La compresión mejora el TTFB
- Guía de Headers de Caché - Cachear archivos comprimidos
- Guía de Recursos Bloqueantes - Entrega de recursos críticos
📚 Volver al Hub de Performance SEO - Explora todos los temas de rendimiento
Referencias
- MDN Web Docs - Content-Encoding
- web.dev - Minify and Compress Network Payloads
- Chrome Developers - Enable Text Compression
- Nginx Documentation - ngx_http_gzip_module
Pruébalo Tú Mismo
¿Listo para optimizar la compresión de tu sitio?
🔧 Descarga UXR SEO Analyzer (Gratis, análisis 100% local)
Disclaimer: Los analizadores en esta extensión son guías de referencia basadas en documentación oficial de MDN, web.dev y Chrome Developers. No representan verdades absolutas sobre cómo los motores de búsqueda evalúan tu contenido—solo los motores de búsqueda conocen sus algoritmos internos. Usa estas recomendaciones como punto de partida para mejorar tu sitio.
Última actualización: 15 de diciembre de 2025