El módulo PageSpeed de Google (mod_pagespeed para Apache y ngx_pagespeed para Nginx) reescribía las páginas al vuelo para comprimir, minificar y convertir imágenes. El proyecto dejó de mantenerse: Google abandonó el desarrollo y el proyecto de la Apache Software Foundation se retiró en 2023, así que no hay versiones para el Nginx de Ubuntu 24.04 ni parches de seguridad. En esta guía verás cómo retirarlo si aún lo tienes y cómo obtener las mismas mejoras con herramientas mantenidas en Nginx o Apache sobre Ubuntu 24.04.

Requisitos previos

  • Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath.
  • Un usuario no root con privilegios sudo.
  • Nginx (paquete nginx de Ubuntu) o Apache (apache2) sirviendo tu sitio en tudominio.com.

Por qué no instalar PageSpeed hoy

Optimización de PageSpeedAlternativa mantenida
Compresión (gzip)gzip y Brotli nativos del servidor web
extend_cacheCabeceras Cache-Control largas con nombres de archivo versionados
rewrite_css, rewrite_javascript, combine_*Minificación en el proceso de build (Vite, esbuild, webpack)
recompress_images, convert_*_to_webpConversión previa con cwebp y negociación por cabecera Accept
lazyload_imagesAtributo HTML nativo loading="lazy"

Hacer estas tareas antes de servir la página, en lugar de en cada petición, consume menos CPU y memoria y no rompe el HTML, que era el problema más habitual de PageSpeed.

Paso 1: Retirar PageSpeed si está instalado

En Apache, comprueba si el módulo está cargado:

sudo apache2ctl -M | grep pagespeed

Si aparece pagespeed_module, desactívalo y elimina el paquete y su repositorio:

sudo a2dismod pagespeed
sudo apt purge mod-pagespeed-stable
sudo rm -f /etc/apt/sources.list.d/mod-pagespeed.list
sudo systemctl restart apache2

En Nginx, ngx_pagespeed solo existía compilado a mano. Comprueba si tu binario lo incluye:

nginx -V 2>&1 | grep -o pagespeed

Si aparece, reinstala el paquete de Ubuntu para volver al binario oficial y elimina las directivas pagespeed de tu configuración:

sudo apt install --reinstall nginx
sudo grep -rl pagespeed /etc/nginx/

Edita cada archivo que devuelva el último comando, borra las líneas que empiezan por pagespeed y comprueba la configuración con sudo nginx -t.

Paso 2: Activar compresión Brotli y gzip

Brotli comprime HTML, CSS y JavaScript entre un 15 y un 20 % más que gzip y lo soportan todos los navegadores actuales. Mantén gzip para clientes antiguos.

Nginx

Instala los módulos de Brotli empaquetados en Ubuntu:

sudo apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static

El paquete los activa en /etc/nginx/modules-enabled/. Crea un archivo de compresión que se incluirá en el bloque http:

sudo nano /etc/nginx/conf.d/compression.conf
# gzip ya está activado con "gzip on;" en nginx.conf: no lo repitas aquí
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xml;

brotli on;
brotli_comp_level 5;
brotli_min_length 256;
brotli_types text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xml;

text/html se comprime siempre y no debe aparecer en las listas. Comprueba y recarga:

sudo nginx -t
sudo systemctl reload nginx

Apache

Ubuntu incluye mod_brotli y mod_deflate. Activa Brotli:

sudo a2enmod brotli
sudo nano /etc/apache2/conf-available/brotli.conf
<IfModule mod_brotli.c>
    AddOutputFilterByType BROTLI_COMPRESS text/html text/plain text/css text/javascript application/javascript application/json application/xml image/svg+xml
</IfModule>
sudo a2enconf brotli
sudo apache2ctl configtest
sudo systemctl reload apache2

Verificación

Pide una página anunciando soporte de Brotli:

curl -s -o /dev/null -D - -H "Accept-Encoding: br, gzip" https://tudominio.com/ | grep -i content-encoding
content-encoding: br

Paso 3: Cabeceras de caché para estáticos

El filtro extend_cache de PageSpeed renombraba los recursos para poder cachearlos durante un año. Si tu build ya genera nombres con hash (app.3f9a1c.js), basta con enviar una cabecera de caché larga.

Nginx

Añade este bloque dentro del server de tu sitio, en /etc/nginx/sites-available/tudominio.com:

location ~* \.(css|js|mjs|woff2|svg|png|jpe?g|gif|webp|avif|ico)$ {
    add_header Cache-Control "public, max-age=31536000, immutable";
    access_log off;
    try_files $uri =404;
}

Apache

Activa mod_expires y mod_headers:

sudo a2enmod expires headers

Añade dentro del <VirtualHost> de tu sitio:

<FilesMatch "\.(css|js|mjs|woff2|svg|png|jpe?g|gif|webp|avif|ico)$">
    ExpiresActive On
    ExpiresDefault "access plus 1 year"
    Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>

Recarga el servidor y verifica sobre un recurso real:

curl -sI https://tudominio.com/css/app.css | grep -i cache-control
cache-control: public, max-age=31536000, immutable

Paso 4: Servir imágenes WebP

En lugar de convertir en cada petición, genera la versión WebP junto al original una vez y deja que el servidor elija según la cabecera Accept del navegador. Instala el conversor:

sudo apt install webp

Convierte las imágenes del sitio creando foto.jpg.webp junto a foto.jpg:

find /var/www/tudominio.com/images -type f \( -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' \) \
  -exec sh -c 'cwebp -quiet -q 80 "$1" -o "$1.webp"' _ {} \;

En Nginx, crea el mapa que decide el sufijo:

sudo nano /etc/nginx/conf.d/webp.conf
map $http_accept $webp_suffix {
    default "";
    "~*image/webp" ".webp";
}

Y en el server de tu sitio, coloca este bloque antes del de estáticos del paso 3:

location ~* \.(jpe?g|png)$ {
    add_header Vary Accept;
    add_header Cache-Control "public, max-age=2592000";
    try_files $uri$webp_suffix $uri =404;
}

Recarga Nginx y comprueba que un navegador con soporte WebP recibe la versión convertida:

sudo nginx -t && sudo systemctl reload nginx
curl -sI -H "Accept: image/webp" https://tudominio.com/images/foto.jpg | grep -i content-type
content-type: image/webp

Para automatizar la conversión de las imágenes nuevas y añadir AVIF, consulta la guía de pipeline de optimización de imágenes.

Paso 5: Minificar y aplicar carga diferida en origen

La minificación y la combinación de CSS y JavaScript deben hacerse al compilar el frontend: herramientas como Vite o esbuild ya minifican en modo producción (npm run build). En sitios PHP como WordPress, un plugin de caché o de optimización cumple la misma función.

Para la carga diferida de imágenes, añade el atributo nativo en las plantillas en lugar de reescribir el HTML en el servidor:

<img src="/images/foto.jpg" alt="Descripción" width="800" height="600" loading="lazy">

Indicar width y height reserva el espacio de la imagen y evita saltos de diseño (CLS). No uses loading="lazy" en la imagen principal visible al cargar, porque retrasaría el LCP.

Solución de problemas

nginx: [emerg] "gzip" directive is duplicate. Has escrito gzip on; en un archivo de conf.d, pero ya está en /etc/nginx/nginx.conf. Elimina la línea duplicada.

unknown directive "brotli". Los módulos no se cargan. Comprueba que existen los enlaces en /etc/nginx/modules-enabled/ con ls /etc/nginx/modules-enabled/ | grep brotli.

Las imágenes siguen llegando como JPEG. Verifica que existe foto.jpg.webp en disco y que ningún otro location con regex anterior captura la petición: Nginx usa el primer bloque regex que coincide.

Conclusión

Has retirado un módulo sin mantenimiento y has cubierto sus optimizaciones principales con compresión Brotli, cabeceras de caché, WebP negociado y carga diferida nativa, todo con paquetes de Ubuntu que reciben actualizaciones. Como siguientes pasos, mide el resultado con PageSpeed Insights, activa HTTP/3 en tu servidor web y automatiza la conversión de imágenes con un temporizador de systemd.