Rendimiento

La velocidad de WordPress: qué hacer y en qué orden

Por Bryan Taylor Reverón 20 min de lectura

Si tu web tarda en cargar, la gente se va antes de leer nada. Esta guía junta, por orden, lo que de verdad hace que una web vaya rápida. Está escrita para quien decide sobre la web, no para quien la desarrolla. Cada apartado dice qué es, por qué importa y qué hay que hacer. Las instrucciones técnicas van al final, en un bloque aparte para quien vaya a hacerlo.

Por qué importa la velocidad de tu web

La velocidad no es un detalle técnico. Es la primera impresión que se lleva quien te visita. Y decide si se queda o se va.

Una web lenta cansa, vende menos y daña tu imagen. Se nota sobre todo en el móvil, donde la gente tiene menos paciencia. Y Google la coloca más abajo en sus resultados. Una web rápida hace que la gente se quede, que compre y que Google te ponga más arriba. Por eso la velocidad es una decisión de negocio, no una tarea de informáticos.

Qué puede salir mal

Mejorar la velocidad tiene sus trampas. Estas son las que más vemos:

  • Tocar sin copia de seguridad. Si algo se rompe, no hay vuelta atrás. Primero la copia, después el cambio.
  • Instalar complementos a ciegas. Cada complemento añade trabajo a cada visita. Dos que hacen lo mismo se estorban.
  • Activar todo a la vez. Algunas mejoras rompen el carrusel de fotos de la portada, un formulario o un mapa. Si activas diez cosas, no sabes cuál lo rompió.
  • Contenido viejo. Cuando la web guarda cada página ya hecha, hay que renovarla al publicar un cambio. Si no, el visitante ve la versión antigua.
  • Cosas que desaparecen. Si la web deja de cargar lo que no se ve, algún vídeo o mapa incrustado puede no aparecer. Tiene solución, pero hay que saberlo.
  • Cambiar sin medir. Sin una medida antes y otra después, no sabes si sirvió de algo.

Las nueve medidas, de un vistazo

Casi todas las listas de consejos repiten lo mismo. Las hemos juntado en nueve medidas, que son también el índice de esta guía. El orden importa: las primeras dan más resultado con menos esfuerzo. Todo esto se puede hacer a mano, o tenerlo de serie con PF Hosting.

  1. Un buen alojamiento y una caché de página (cada página guardada ya hecha). Resuelve la mayor parte del problema.
  2. Tu web copiada en servidores repartidos por el mundo. Para que cargue rápido desde cualquier sitio.
  3. Imágenes más ligeras. Son casi siempre lo que más pesa.
  4. Código más ligero. Quitar lo que sobra y dejar para después lo que no hace falta al principio.
  5. Que el texto se vea aunque el tipo de letra tarde en llegar.
  6. No cargar lo que el visitante todavía no ve.
  7. Una plantilla ligera, pocos complementos y una base de datos limpia. Menos trabajo en cada visita.
  8. Que el servidor envíe los ficheros comprimidos.
  9. Medir antes y después. Sin medida no hay mejora, solo opiniones.

1. Alojamiento y caché: la base de todo

Lo primero es el servidor donde vive tu web. Una buena plantilla no salva a un servidor saturado o mal puesto. Por eso es el primer sitio donde mirar.

Qué pedirle a un alojamiento para WordPress

No todos los alojamientos tratan igual a WordPress. Antes de contratar, o de quedarte donde estás, comprueba esta lista.

  • Cada página guardada ya hecha, por el propio servidor y no solo por un complemento. Es la diferencia entre fabricar la página en cada visita o servirla ya hecha.
  • Actualizaciones hechas por ellos, con copia de seguridad previa. Un WordPress sin actualizar es lento y, sobre todo, inseguro.
  • Un filtro que pare los ataques antes de que lleguen a tu web.
  • Tu web copiada en servidores repartidos por el mundo, para que las imágenes no salgan siempre de tu servidor.
  • Que pueda crecer cuando suban las visitas, sin volver a migrar.
  • Un soporte que responde cuando algo falla, con personas que conocen WordPress.
  • El software del servidor, al día. WordPress se apoya en otro software para funcionar. Cada versión nueva suele ir más rápida.

Si tu alojamiento no cumple varios puntos de esta lista, la mejora más rentable no es otro complemento. Es cambiar de alojamiento. Nosotros montamos PF Hosting con un servidor propio para tu web y servidores repartidos por el mundo. Lleva también un filtro que para los ataques, copia de seguridad todos los días y las actualizaciones hechas por nosotros.

La caché: en tu servidor y cerca del visitante

Hay dos formas de evitar que tu web fabrique cada página en cada visita. No compiten: se complementan.

La página guardada en tu servidor la hace un complemento o el propio servidor. Guarda la página ya montada y la sirve tal cual. Así el servidor trabaja menos y aguanta más visitas con lo mismo.

Tu web también se puede guardar en muchos servidores repartidos por el mundo. Cada visitante la recibe del que tiene más cerca. Quien te visita desde lejos no tiene que llegar hasta tu servidor.

Lo habitual es usar las dos formas. Con una condición: al publicar un cambio hay que renovar las dos. Si no, el visitante ve contenido viejo.

2. Tu web, copiada en servidores repartidos por el mundo

Esos servidores guardan tus imágenes, tu código y tus tipos de letra en muchos puntos del mundo. Los sirven desde el más cercano a cada visitante. La web carga antes, tu servidor trabaja menos y, de paso, queda más protegido de los ataques. Nosotros los montamos pieza a pieza, para ajustarlos a cada web. Cómo se hace está en el bloque final.

Bien montados hacen dos cosas más. Delante se pone un filtro que para los ataques antes de que lleguen a tu servidor. Y el navegador de quien te visita se guarda una copia de las imágenes y del código durante mucho tiempo. Así no vuelve a pedir lo que ya tiene. Las dos cosas forman parte de PF Hosting.

3. Imágenes: el peso que más se nota

Las imágenes son casi siempre la mayor parte del peso de una página. Lo básico está en optimizar imágenes en WordPress. Comprimirlas, subirlas ya con el tamaño al que se van a ver y elegir un formato moderno. Y servirlas desde los servidores repartidos por el mundo.

Aquí añadimos dos técnicas. La primera: un formato de imagen moderno que pesa bastante menos con la misma calidad. Un complemento convierte las imágenes y guarda la versión ligera junto a la original. La segunda: avisar al navegador desde el principio de cuál es la imagen grande de la primera pantalla, para que la muestre antes. Lo que Google más mira para ponerte nota es cuánto tarda en verse esa imagen grande. Por eso el aviso compensa.

4. Código más ligero

Cada plantilla y cada complemento añaden sus propios ficheros de código. Sin control, una página pide decenas de ficheros antes de mostrar nada. Tres cosas reducen ese trabajo:

  • Quitar lo que sobra: espacios en blanco y las notas que el programador dejó escritas dentro del código. El fichero pesa menos y funciona igual.
  • Juntar varios ficheros en uno, para hacer menos peticiones.
  • Dejar para después lo que no hace falta para mostrar lo primero que se ve.

Hay complementos que hacen las tres cosas. Elijas el que elijas, ve despacio. Activa una opción y comprueba la web en varias páginas y en el móvil. Solo entonces activa la siguiente. Dejar código para después puede romper el carrusel de fotos de la portada, un formulario o un mapa. Si pasa, conviene saber qué opción lo provocó. El detalle, opción por opción y a mano, sin complementos, está en hacer más ligero el código de tu WordPress.

5. Tipos de letra: que el texto se vea desde el primer momento

Un tipo de letra propio tarda en descargarse. Mientras llega, el navegador puede dejar el texto invisible hasta un segundo. La solución es sencilla: que muestre el texto con una letra del sistema y la cambie cuando la buena esté lista. Google lo recomienda y lo mide.

Dos medidas más que ayudan igual. Usa pocos tipos de letra distintos, y de cada uno solo lo que necesitas de verdad: la normal y la negrita. Y guarda los tipos de letra en tu propio servidor, en vez de pedirlos a Google. Así los datos de quien te visita no salen de tu servidor. Lo explicamos en optimizar los tipos de letra en WordPress.

6. No cargar lo que nadie ve todavía

Las imágenes, vídeos y mapas que están por debajo de la primera pantalla no hacen falta al principio. Se le puede decir al navegador que espere: que los descargue solo cuando el visitante baja hasta ellos. A eso se le llama carga diferida. WordPress ya lo hace de serie con las imágenes. Un complemento lo extiende a vídeos y fondos. La página pesa menos y se muestra antes.

Un aviso, con un caso real. Tras migrar la web de un cliente, algunos vídeos y mapas incrustados dejaron de verse en varias páginas. En el editor se veían bien. El culpable era la carga diferida: ese contenido no aguantaba cargarse después. La solución no fue desactivarla, sino excluir ese elemento. Casi todos los complementos tienen una lista de exclusiones. Si algo desaparece después de activarla, empieza por ahí.

7. Plantilla ligera, pocos complementos y base de datos limpia

Tres medidas que no cuestan dinero y que se olvidan a menudo:

  • Usa una plantilla ligera. Una plantilla con cientos de opciones y un editor visual carga mucho código que tu web no usa. Cuanto menos haga, más rápido irá.
  • Desactiva y borra los complementos que no necesitas. Cada uno añade trabajo a cada visita. Si dos hacen lo mismo, quédate con uno. Tenemos una entrada sobre qué complementos de velocidad funcionan bien juntos y cuáles no.
  • Limpia la base de datos. Las versiones antiguas de cada página, los comentarios basura y los datos caducados hacen que la base de datos crezca sin necesidad. Un complemento lo hace con dos clics. Y conviene limitar cuántas versiones antiguas guarda WordPress. Lo explicamos en optimizar la base de datos de WordPress.

8. Que el servidor envíe los ficheros comprimidos

Comprimir lo que viaja hasta el navegador reduce su tamaño. Pregunta a tu proveedor si tiene activada esa compresión. Es gratis y cualquier alojamiento serio la tiene. Si te dice que no, es mala señal sobre todo lo demás.

9. Medir: antes, después y sin engañarse

Sin una medida previa no sabes si una mejora ha servido de algo. Google tiene una herramienta de velocidad gratuita. Escribes la dirección de tu web, pulsas «Analizar» y te da un informe para móvil y otro para ordenador. Cada uno trae una nota de 0 a 100 y una lista de recomendaciones, ordenadas por lo que más ayuda.

Las cuatro notas que hay que entender

  • Cuánto tarda en aparecer lo primero en pantalla. Es el momento en que el visitante sabe que la página está llegando.
  • Cuánto tarda en verse lo más grande de la primera pantalla, casi siempre una imagen o un titular. Es la nota que más pesa.
  • Cuánto se desplaza el diseño mientras carga. Es ese botón que cambia de sitio justo cuando ibas a pulsarlo.
  • Cuánto tarda la página en responder a lo que haces. Aquí es donde el código pesado pasa factura.

La nota de arriba es una simulación. La herramienta muestra además lo que de verdad le pasa a la gente que te visita, cuando la web tiene visitas suficientes. Esos datos valen más. Cómo leer cada recomendación está en la nota de velocidad que Google le pone a tu web.

El orden correcto: medir, aplicar, volver a medir

  1. Haz una copia de seguridad. Antes de tocar nada. Si algo sale mal, vuelves atrás en minutos.
  2. Mide el estado actual, en móvil y en ordenador, y guarda el informe. Mide también dos o tres páginas interiores, no solo la portada.
  3. Aplica una medida cada vez, en el orden de esta guía. Primero el alojamiento y la página guardada, luego las imágenes y los servidores repartidos, después el código.
  4. Vuelve a medir después de cada cambio y compara con el informe guardado. Si una medida no mejora nada o rompe algo, deshazla.
  5. Repite en unas semanas. Los complementos se actualizan y el contenido crece. Lo que hoy está bien puede dejar de estarlo.

Si tu web no es lenta en general, sino en momentos concretos o solo cuando entras a editarla, el problema suele ser otro. Lo tratamos en WordPress lento: causas posibles y cómo aumentar la velocidad.

Y si prefieres no hacerlo tú

Escríbenos con la dirección de tu web. Te decimos cómo iría en PF Hosting y qué cambiaría. Y si tienes a alguien que toque la web, pásale el bloque de abajo.

Con qué lo hacemos

PF Hosting va sobre AWS, los centros de datos de Amazon, en la Unión Europea. Cada web tiene su propio servidor, sin dirección pública. Delante va Amazon CloudFront como CDN, con AWS WAF de filtro de ataques. Las copias de seguridad son diarias y las actualizaciones las hace nuestro equipo.

Los complementos que nombra esta guía son otra cosa: los usamos cuando trabajamos sobre el WordPress de un cliente. WP Offload Media lleva las imágenes a un bucket privado de S3 y las sirve por la CDN. EWWW Image Optimizer las convierte a WebP. WP-Optimize limpia la base de datos. Para minificar, combinar y diferir CSS y JavaScript, WP Rocket (de pago) o Autoptimize (gratuito). La caché de página la hace el servidor, o WP Super Cache, W3 Total Cache o WP Rocket. Cloudflare es la alternativa de CDN con caché del HTML en el borde. Compresión Gzip o Brotli en el servidor. Medimos con Google PageSpeed Insights.

Para quien lo va a hacer: los pasos con comandos

Lo que sigue es para la persona que va a tocar la web. Si no eres tú, pásaselo. Haz copia de seguridad antes de cada paso y prueba la web en varias páginas después de cada cambio.

Caché de página y caché en el borde

La caché en el servidor la hacen plugins como WP Super Cache, W3 Total Cache o WP Rocket. O el propio servidor, si está preparado. Guarda el HTML ya generado, y a veces también consultas a la base de datos y objetos de PHP. Reduce el trabajo del servidor, así que aguanta más visitas con los mismos recursos.

La caché en el borde es la que hace una CDN. Guarda copias del contenido en decenas de puntos y las sirve desde el más cercano al visitante. Algunas CDN, como Cloudflare con su optimización automática para WordPress, guardan incluso el HTML en el borde. La combinación habitual es caché de página en el servidor más CDN para los ficheros estáticos. Con las dos activas, al publicar un cambio hay que vaciar las dos.

Tres ajustes que no cuestan dinero. Limita el número de revisiones en wp-config.php. Limpia revisiones, spam y transitorios caducados con WP-Optimize. Y activa la compresión Gzip o Brotli en el servidor.

Montar la CDN con CloudFront, paso a paso

Usamos Amazon CloudFront porque se ajusta pieza a pieza a lo que necesita cada web.

1. Un bucket de S3 privado para el contenido estático. En la consola de AWS, entra en S3 y crea un bucket. Ponle el mismo nombre que tendrá el subdominio de la CDN (por ejemplo, cdn.ejemplo.com): lo identificarás mejor. Elige la misma región donde está tu servidor. Si tu WordPress vive en Amazon Lightsail, el bucket y la instancia tienen que estar en la misma región. Deja las ACL desactivadas, marca «Bloquear todo el acceso público» y conserva el resto de opciones por defecto. El bucket no se abre al público: es CloudFront quien lo leerá, con un permiso específico que se crea más adelante.

2. El TLS del subdominio, en ACM. Para que la CDN sirva por HTTPS hace falta un TLS público para el subdominio. Se pide en AWS Certificate Manager (ACM): «Request a public certificate», nombre cdn.ejemplo.com, validación por DNS y algoritmo RSA 2048. ACM te da un registro CNAME que tienes que crear en el DNS de tu dominio. Cuando lo detecta, marca el TLS como verificado; suele tardar unos minutos. Si tu dominio está en Route 53, un botón crea el registro por ti. Un detalle que ahorra tiempo. Para CloudFront, el TLS tiene que pedirse en la región de Virginia del Norte (us-east-1), sea cual sea la región del bucket.

3. La distribución de CloudFront. En CloudFront, crea una distribución nueva con esta configuración:

  • Origen: el bucket de S3 recién creado. En «Origin access» elige «Origin access control settings» y crea el control. CloudFront avisa de que hay que actualizar los permisos del bucket: se hace al final.
  • Comportamiento por defecto: redirigir HTTP a HTTPS; métodos permitidos GET, HEAD y OPTIONS, con OPTIONS también en los métodos cacheados.
  • Políticas: política de caché «CachingOptimized», política de petición al origen «CORS-S3Origin» y política de cabeceras de respuesta «CORS-and-SecurityHeadersPolicy». Esta última añade cabeceras de seguridad a todo lo que sirve la CDN.
  • Alcance: «Use all edge locations» si tienes visitantes en varios continentes. Si casi todos están en Europa, la opción limitada a Europa y Norteamérica cuesta menos y rinde igual.
  • Nombre alternativo (CNAME): cdn.ejemplo.com, y en el desplegable, el TLS que creaste en ACM.
  • Versiones de HTTP: marca HTTP/2 y HTTP/3.

4. DNS y permiso del bucket. Copia el «Distribution domain name» de la distribución (algo como d1abc234.cloudfront.net). Crea en tu DNS un registro CNAME de cdn.ejemplo.com hacia ese valor. Después, en la pestaña «Origins» de la distribución, edita el origen. En «Origin access» hay un botón «Copy policy» que copia la política que autoriza a esa distribución a leer el bucket. Pégala en la política del bucket de S3 (sección «Bucket policy»). Comprueba que el primer carácter sea la llave de apertura y que no sobre ningún espacio delante. Para comprobar que todo funciona, sube una imagen cualquiera al bucket y ábrela con la URL de la CDN: https://cdn.ejemplo.com/imagen.png. Si se ve, la CDN está lista.

Para que WordPress use la CDN, un plugin como WP Offload Media envía cada imagen que subes al bucket y reescribe sus URL. Con EWWW Image Optimizer convirtiendo las imágenes a WebP, los dos plugins forman una combinación que nos ha funcionado bien en AWS.

5. Funciones de CloudFront: WebP y CORS. CloudFront permite ejecutar pequeñas funciones en el borde, sin servidor, para cambiar peticiones y respuestas. Dos casos reales que hemos resuelto así.

El primero: servir la versión WebP de cada imagen sin tocar el HTML. Una función en «viewer request» reescribe la petición de un .jpg o .png hacia el mismo fichero con .webp añadido. Es como los guarda EWWW.

function handler(event) {
    var request = event.request;
    if (request.uri.match(/\.(jpe?g|png)$/)) {
        request.uri += '.webp';
    }
    return request;
}

El segundo: al activar un plugin de caché, las fuentes servidas desde la CDN dejaron de cargar. El error era «has been blocked by CORS policy». La CDN y la web no tienen el mismo origen, así que el navegador exige la cabecera Access-Control-Allow-Origin. Una función en «viewer response» la añade solo a los ficheros de fuente:

function handler(event) {
    var response = event.response;
    if (event.request.uri.match(/\.(ttf|woff2?)$/)) {
        response.headers['access-control-allow-origin'] = { value: '*' };
    }
    return response;
}

Dos avisos. CloudFront admite una sola función por evento y distribución: si necesitas dos reglas en el mismo evento, van dentro de la misma función. Y entre CloudFront Functions y Lambda@Edge, para este tipo de reglas preferimos las primeras: son más simples y aceptan más peticiones simultáneas.

6. WAF y cabeceras de caché. Delante de la distribución se puede activar AWS WAF, un cortafuegos de aplicaciones. Filtra las peticiones maliciosas antes de que lleguen a tu servidor, sin penalizar el rendimiento. Y a todos los ficheros estáticos se les sirven cabeceras de caché largas. Así el navegador del visitante no vuelve a pedir una imagen o una hoja de estilo que ya tiene. Es lo que montamos en nuestros proyectos de CDN privada y es también lo que lleva PF Hosting.

WebP con EWWW Image Optimizer

WebP pesa bastante menos que JPEG o PNG con la misma calidad visual. EWWW Image Optimizer convierte las imágenes y guarda la versión WebP junto a la original. Para que el servidor sirva el WebP a los navegadores que lo aceptan, hacen falta unas reglas de reescritura en .htaccess. El plugin intenta insertarlas, pero no siempre lo consigue, y una vez insertadas cuesta volver a encontrarlas. Son estas:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{HTTP_ACCEPT} image/webp
    RewriteCond %{REQUEST_FILENAME} (.*)\.(jpe?g|png|gif)$
    RewriteCond %{REQUEST_FILENAME}\.webp -f
    RewriteCond %{QUERY_STRING} !type=original
    RewriteRule (.+)\.(jpe?g|png|gif)$ %{REQUEST_URI}.webp [T=image/webp,L]
</IfModule>
<IfModule mod_headers.c>
    <FilesMatch "\.(jpe?g|png|gif)$">
        Header append Vary Accept
    </FilesMatch>
</IfModule>
AddType image/webp .webp

Si sirves las imágenes por una CDN, no necesitas estas reglas. EWWW, incluso en su versión gratuita, puede hacer la sustitución por JavaScript, o la puede hacer la propia CDN con la función del apartado anterior.

Avisar al navegador de cuál es la imagen grande

La nota de velocidad que más pesa (LCP, Largest Contentful Paint) mide cuánto tarda en aparecer el elemento más grande de la pantalla inicial. En casi todas las páginas ese elemento es una imagen. Si el navegador la descubre tarde, la nota sufre. La solución es avisarle desde el principio con rel="preload". No conviene abusar de esta etiqueta, pero para la imagen destacada de cada entrada compensa. Este código, en el functions.php del tema, la precarga automáticamente:

add_action('wp_head', function () {
    if (has_post_thumbnail()) {
        $url = wp_get_attachment_url(get_post_thumbnail_id());
        echo '<link rel="preload" as="image" href="' . esc_url($url) . '">';
    }
});

Para una imagen concreta de una sola página basta con añadir la etiqueta a mano en el <head> de esa página.

<link rel="preload" as="image" href="https://cdn.ejemplo.com/portada.jpg">

WP Rocket o Autoptimize

Los dos plugins que recomendamos para minificar, combinar y diferir son WP Rocket, de pago, y Autoptimize, gratuito. Hacen lo mismo con distinta profundidad. En WP Rocket, en «Optimización de archivos», se activan cuatro cosas. La minificación y la combinación de CSS y de JavaScript, la carga diferida del JavaScript y la generación de CSS crítico. Después, «Vaciar caché». En Autoptimize, en «Ajustes», se marcan «Optimizar CSS», «Optimizar JavaScript» y, si se quiere, «Optimizar HTML» y la inserción de CSS crítico. Se guarda vaciando la caché. Otros plugins que a veces aparecen en estas listas no son optimizadores. Un editor visual de CSS o un tema de páginas de venta no minifican nada. Con HTTP/2 y HTTP/3, combinar importa menos que antes, pero sigue ayudando cuando hay muchos ficheros pequeños.

Fuentes: font-display swap

La propiedad font-display: swap le dice al navegador que muestre el texto con una fuente del sistema y lo cambie cuando la buena esté lista. Google lo recomienda como buena práctica y lo mide en PageSpeed. En una fuente propia se declara así:

@font-face {
    font-family: 'MiFuente';
    src: url('/fonts/mifuente.woff2') format('woff2');
    font-display: swap;
}

Por defecto, muchos temas y maquetadores cargan las fuentes con el valor «auto», que puede dejar el texto en blanco hasta un segundo. Casi todos permiten cambiarlo desde sus propios ajustes de tipografía. Si el tema regenera sus ficheros de fuentes, hay que volver a generarlos después del cambio. Aloja las fuentes en tu propio servidor o CDN, en vez de pedirlas a Google Fonts. Así los datos del visitante no salen hacia un tercero.

Carga diferida: excluir un iframe

WordPress aplica loading="lazy" a las imágenes de serie. Plugins como EWWW o WP Rocket lo extienden a iframes y fondos. El caso real del apartado 6: tras migrar la web de un cliente a AWS, algunos iframes insertados como HTML dejaron de mostrarse. El inspector del navegador lo explicó. El iframe llevaba una clase lazyloaded que no estaba en el HTML original; la había añadido EWWW Image Optimizer. El contenido de ese iframe no soportaba cargarse en diferido. La prueba definitiva fue colocar el iframe en un punto de la página que no estuviera a la vista al cargar: ahí funcionaba.

La solución: añadir una clase propia al iframe y escribirla en el apartado de exclusiones de los ajustes de EWWW. Después, guardar y vaciar la caché. Casi todos los plugins de carga diferida tienen una lista de exclusiones parecida.