Ver contenido
Introducción
La compresión de texto es una de las formas más efectivas de reducir tamaños de archivo y mejorar los tiempos de carga de página. Al comprimir recursos basados en texto (HTML, CSS, JavaScript, JSON, XML), puedes reducir los tamaños de transferencia en un 60-90%, mejorando directamente TTFB, FCP y la velocidad general de página.
La mayoría de los servidores web modernos y CDNs soportan compresión, pero muchos sitios aún sirven recursos sin comprimir—dejando ganancias significativas de rendimiento sobre la mesa.
Cómo Funciona la Compresión de Texto
Cuando un navegador solicita un recurso, le dice al servidor qué formatos de compresión soporta mediante el header Accept-Encoding. El servidor entonces comprime la respuesta e indica el método de compresión en el header Content-Encoding.
Flujo de Solicitud/Respuesta:
┌─────────────────────────────────────────────────────────────┐
│ 1. Navegador envía solicitud: │
│ GET /styles.css HTTP/1.1 │
│ Accept-Encoding: gzip, deflate, br │
│ │
│ 2. Servidor comprime y responde: │
│ HTTP/1.1 200 OK │
│ Content-Encoding: br │
│ Content-Length: 12540 (comprimido) │
│ [Contenido CSS comprimido con Brotli] │
│ │
│ 3. Navegador descomprime y usa: │
│ Original: 85 KB → Comprimido: 12 KB (¡86% menor!) │
└─────────────────────────────────────────────────────────────┘
Algoritmos de Compresión Comunes
Gzip
El formato de compresión más ampliamente soportado. Disponible en prácticamente todos los servidores y soportado por todos los navegadores desde principios de los 2000.
| Aspecto | Detalles |
|---|---|
| Soporte de Navegadores | 100% (todos los navegadores) |
| Ratio de Compresión | 60-80% de reducción |
| Costo de CPU | Bajo a moderado |
| Mejor Para | Respaldo universal |
Brotli
Un algoritmo de compresión más nuevo desarrollado por Google, que ofrece 15-25% mejor compresión que gzip con velocidades de descompresión similares.
| Aspecto | Detalles |
|---|---|
| Soporte de Navegadores | 97%+ (todos los navegadores modernos) |
| Ratio de Compresión | 70-90% de reducción |
| Costo de CPU | Mayor compresión, descompresión similar |
| Mejor Para | Assets estáticos, tráfico HTTPS |
Deflate
Un algoritmo más antiguo en el que se basa gzip. Raramente usado directamente hoy.
| Aspecto | Detalles |
|---|---|
| Soporte de Navegadores | Universal |
| Ratio de Compresión | Similar a gzip |
| Mejor Para | Solo sistemas legacy |
¿Qué Debe Comprimirse?
Comprimir Estos (Recursos Basados en Texto)
| Tipo de Recurso | Ahorro Típico | Notas |
|---|---|---|
| HTML | 60-80% | Siempre comprimir |
| CSS | 70-85% | Muy compresible |
| JavaScript | 60-80% | Ahorros significativos |
| JSON/XML | 70-90% | Respuestas de API se benefician mucho |
| SVG | 50-70% | Gráficos vectoriales basados en texto |
| Texto plano | 60-80% | Logs, feeds, etc. |
No Comprimir Estos (Ya Comprimidos)
| Tipo de Recurso | Por Qué No |
|---|---|
| Imágenes (JPEG, PNG, WebP) | Ya comprimidas; puede aumentar tamaño |
| Videos (MP4, WebM) | Ya comprimidos |
| Fuentes (WOFF2) | Ya comprimidas |
| ZIP/PDF | Ya comprimidos |
Impacto en Métricas de Rendimiento
La compresión de texto mejora múltiples métricas de rendimiento:
| Métrica | Cómo Ayuda la Compresión |
|---|---|
| TTFB | Servidor puede enviar respuesta más pequeña más rápido |
| FCP | CSS/JS crítico llega antes |
| LCP | Entrega de HTML más rápida mejora LCP |
| Speed Index | Progreso visual general mejora |
| Total Blocking Time | Menos JavaScript para analizar |
Ejemplo de Ahorro en el Mundo Real
Antes de Compresión:
├── index.html: 45 KB
├── styles.css: 120 KB
├── app.js: 350 KB
├── vendor.js: 280 KB
└── Total: 795 KB
Después de Compresión Brotli:
├── index.html: 9 KB (80% menor)
├── styles.css: 18 KB (85% menor)
├── app.js: 85 KB (76% menor)
├── vendor.js: 72 KB (74% menor)
└── Total: 184 KB (¡77% menor!)
Ahorro de Tiempo en 3G: ~5.5 segundos más rápido
Problemas Comunes de Compresión
Problema 1: No Hay Compresión Habilitada
Problema: El servidor sirve archivos sin ninguna compresión.
Solución: Habilita gzip o Brotli en la configuración de tu servidor web.
Problema 2: Comprimir Archivos Ya Comprimidos
Problema: El servidor intenta comprimir imágenes o fuentes WOFF2, desperdiciando CPU.
Solución: Configura el servidor para solo comprimir tipos MIME basados en texto.
Problema 3: Solo Gzip (Sin Brotli)
Problema: Perdiendo 15-25% de ahorros adicionales de Brotli.
Solución: Habilita Brotli para tráfico HTTPS con respaldo gzip.
Problema 4: Nivel de Compresión Bajo
Problema: Usando configuración de compresión más rápida para assets estáticos.
Solución: Usa niveles de compresión más altos para archivos estáticos pre-comprimidos.
Verificando Tu Compresión
Usando DevTools del Navegador
- Abre DevTools → pestaña Network
- Haz clic en cualquier recurso de texto (HTML, CSS, JS)
- Verifica Response Headers buscando
Content-Encoding - Compara columnas “Size” vs “Transferred”
Usando Lighthouse
Ejecuta una auditoría de Lighthouse y busca:
- “Enable text compression” - Lista recursos que podrían comprimirse
- Muestra ahorros estimados en KB y tiempo
Usando curl
# Verificar si la compresión está habilitada
curl -I -H "Accept-Encoding: gzip, br" https://ejemplo.com
# Buscar: Content-Encoding: gzip (o br)
Implementación
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
Aprende más sobre optimizar la entrega de recursos:
- Guía de Optimización de TTFB - La compresión mejora directamente el TTFB
- Recursos Bloqueantes Explicado - Comprimir recursos críticos
- Carga de Fuentes Explicado - Formatos de compresión de fuentes
📚 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
¿Quieres verificar si tu sitio usa compresión?
🔧 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