Logo de Area 73

WPO: un año midiendo el rendimiento de esta web


4 min de lectura
wpoperformancegoogle-core-web-vitalsbest-practices
En este artículo

La idea en una frase

Medir el rendimiento solo sirve si la medida es barata de mantener.

Esto empezó en agosto de 2025 como un borrador sobre los Core Web Vitals de Google y Lighthouse. Se quedó a medias en el «plan de ataque». Un año después, este es el final: qué se montó, qué se tiró y qué números quedan.

Punto de partida

Después de crear esta web app, erades.com, me voy a centrar en los Core Web Vitals de Google. Para esta tarea me voy a centrar en Lighthouse.

Las primeras mediciones (agosto de 2025, móvil) daban 94 en «Sobre mí», 93 en un post y 69 en la búsqueda, con un LCP de 6,8 s.

Primeros pensamientos

Los datos arrojan buenos resultados; en parte se debe al stack tecnológico utilizado (server side rendering y static site generation) y al meta-framework seleccionado, Astro.

Pero para conseguir unos datos aceptables el desarrollador tiene que ser experto y haber peleado mucho en batallas de front para entender las mejores prácticas.

Aun así siempre se escapan cosas, y se debería tener una forma de controlar los Core Web Vitals desde el principio para poder ir mejorando los números. Por otro lado, para conseguir esto habría que incluir estas comprobaciones de forma programática.

Hoy en día los test unitarios y los e2e o funcionales forman parte ya del ADN de los desarrolladores. Sin embargo, veo que los test automáticos de regresión visual y los de rendimiento no acaban de calar, en parte creo que por el aumento del tiempo para ejecutar las pipelines.

Considero que los test automáticos de regresión visual son esenciales: si tuviera que elegir entre test unitarios o de componentes y test de regresión visual, optaría por los de regresión.

En el caso de los test de WPO, creo que los desarrolladores no se dan cuenta del valor que suponen para negocio, y piensan más en el trabajo que les supone hacerlos que en el beneficio.

Lo que se montó: LHCI con servidor

El plan era el de manual: Lighthouse CI en local y en la CI, con presupuestos que rompen el build y un servidor LHCI guardando el histórico.

Se montó: servidor LHCI en Docker, con su base SQLite versionada en Git LFS. Se usó diez días y se abandonó. Cuando se retomó un año después, hizo falta instalar git-lfs, bajar 124 MB y sacar un token de dentro del propio SQLite antes de poder medir nada.

  • ~20 MB de LFS por ejecución para guardar unas 40 cifras.
  • Las mismas cifras en texto plano ocupan ~1,8 KB.

Las trampas de medir

Peor que el coste era que parte de lo medido no significaba nada:

  • Local y producción mezclados. La suite medía URLs de localhost junto a las de producción. La mitad de las medidas «mejoraban» al desplegar, no al cambiar código, y los LCP de 15-22 s en local eran el portátil, no la web.
  • Un «desktop» que no lo era. La config de escritorio solo cambiaba la pantalla y heredaba el throttling de móvil: viewport de escritorio sobre 4G lento con la CPU a 1/4. Arreglado eso, la home pasó de perf 74 a 93 sin tocar una línea del sitio.
  • El ruido del runner. En GitHub Actions, dos ejecuciones idénticas varían ±5 puntos de perf. Un presupuesto de tiempos que rompe el build con ese ruido falla al azar.

Lo que quedó: un fichero de texto en una rama

El servidor se sustituyó por un NDJSON: una línea por URL y form factor, con la mediana de 3 ejecuciones contra producción. Vive en una rama huérfana metrics (si estuviera en master, cada commit semanal del bot dispararía un despliegue), y Git es la base de datos: git log -p es la gráfica.

La lección que más rinde: los bytes son deterministas, los tiempos no. Una subida en el peso de JS es siempre una regresión real; una bajada de 3 puntos de perf no dice nada. Los tiempos se leen como tendencia a semanas.

Resultados

Con una medida fiable, las mejoras salieron solas, una por PR: portadas redimensionadas por Astro, avatar y logo a su tamaño real, fuentes recortadas a latín (237 → 80 KB precargados), CSS inline para quitar el único recurso bloqueante, gtag.js después de load y la home prerenderizada precargando la imagen del LCP.

Home en móvil: el peso total baja de 2,74 MB a 0,39 MB y el de imágenes de 2,38 MB a 0,09 MB entre agosto y octubre de 2026TotalImágeneshome /es, móvil, bytes transferidos2,74 MB0,39 MB2,38 MB0,09 MB21-08-202605-10-2026
Home /es Agosto 2026 Octubre 2026
Peso total (móvil) 2,74 MB 0,39 MB
LCP móvil 12,1 s 2,3 s
Perf desktop 93 100
Perf móvil 75 92

Lo que no se arregló: en el runner, algunas cargas móviles se quedan en blanco ~1 s más sin causa reproducible en local, y esa fila marca LCP de ~4 s. Se aceptó en vez de perseguirlo.

Opinión

Mantengo lo que escribí hace un año: el rendimiento hay que medirlo desde el principio y de forma automática. Lo que cambio es cómo. El plan de manual (servidor, presupuestos, cuadros de mando) murió por su propio peso; lo que ha durado es un fichero de texto que cualquiera lee con jq.

Y los presupuestos que rompen el build no los echo de menos: con ±5 puntos de ruido, un test de rendimiento basado en tiempos es un test flaky. Si algún día vuelven, serán sobre bytes.

Bibliografía: