WPO: un año midiendo el rendimiento de esta web
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
localhostjunto 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 /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:
- Web Vitals. web.dev, Google
- Introduction to Lighthouse. Chrome for Developers
- Lighthouse CI. GoogleChrome
- Lighthouse Variability. GoogleChrome