wandres.dev
ONTOLOGÍA · El mapa del rendimiento web

Las tres fases: carga, interacción, estabilidad

El eje que organiza todo el rendimiento web: qué problema distinto plantea cada fase, qué la causa y por qué una métrica de una fase no dice nada de las otras.

⏱ 17 min

El rendimiento web no es un problema, son tres, y tienen causas casi disjuntas. Una página puede pintar en 800 ms y responder a un clic en 900; otra puede tardar cuatro segundos en aparecer y luego ir como la seda. Confundirlas lleva a atacar el síntoma equivocado con la herramienta equivocada. Esta lección fija el eje que estructura el track entero.

🎯 Al terminar esta lección sabrás
  • Separar los tres problemas de rendimiento y asignar a cada uno su causa dominante.
  • Explicar por qué optimizar la fase de carga no mejora la de interacción, y viceversa.
  • Situar cada Core Web Vital en su fase y saber qué zona ciega deja.
  • Reconocer, ante un síntoma descrito por un usuario, en qué fase buscar.

Las tres preguntas del usuario

Un usuario que llega a una página se hace, sin formularlas, tres preguntas en secuencia. Cada una define una fase.

¿Está pasando algo? ¿Ya puedo leer? Esa es la fase de carga. Va desde que el usuario inicia la navegación hasta que el contenido principal está en pantalla. El enemigo aquí es la red y el bloqueo del renderizado: bytes que hay que traer, conexiones que hay que abrir, recursos que impiden pintar hasta que lleguen. La métrica de referencia es el LCP, apoyada en TTFB y FCP como diagnósticos.

¿Me responde cuando toco? Esa es la fase de interacción. Empieza en cuanto hay algo con lo que interactuar y dura toda la vida de la página. El enemigo aquí no es la red sino el hilo principal: una única cola de trabajo donde compiten la ejecución de JavaScript, el cálculo de estilos, el layout y el pintado. Si esa cola está ocupada cuando el usuario pulsa, el evento espera. La métrica de referencia es el INP.

¿Se está quieto lo que estoy mirando? Esa es la fase de estabilidad. Es transversal a las otras dos: mide si el contenido salta bajo el dedo o bajo la mirada. El enemigo es el contenido que llega tarde y ocupa espacio que no estaba reservado: imágenes sin dimensiones, fuentes web que sustituyen a la de respaldo con otra métrica, anuncios y avisos de cookies inyectados por encima. La métrica de referencia es el CLS.

La independencia entre fases no es una intuición, es aritmética. Un sitio estático de texto puro servido desde una CDN tiene un LCP excelente y un INP perfecto porque no hay JavaScript que bloquee nada. Una aplicación de una sola página bien optimizada puede pintar en un segundo y luego bloquear el hilo 800 ms cada vez que escribes en un campo de búsqueda porque filtra veinte mil elementos en cada pulsación. Son enfermedades distintas.

Por qué las causas no se solapan

Cada fase tiene un recurso escaso distinto, y ahí está la clave de por qué las optimizaciones no se transfieren.

Fase Recurso escaso Palanca principal Palanca inútil
Carga Viajes de ida y vuelta y bytes en la ruta crítica Reducir bloqueo, adelantar el descubrimiento del recurso, comprimir Trocear tareas del hilo principal
Interacción Milisegundos libres del hilo principal Menos JavaScript, ceder el hilo, sacar trabajo del hilo Precargar imágenes
Estabilidad Espacio reservado en el layout Declarar dimensiones, reservar hueco, ajustar métricas de fuente Comprimir más

Un ejemplo que lo hace evidente. Supón que tu LCP es malo porque la imagen del hero pesa 900 KB. La conviertes a AVIF y baja a 90 KB. Excelente: has recortado la fase de carga. ¿Cuánto has mejorado el INP? Cero. El INP lo determina cuánto tiempo tiene el hilo principal ocupado cuando el usuario pulsa, y una imagen se decodifica de forma que no cambia esa aritmética de manera significativa.

Y al revés: mueves el cálculo pesado de tu tabla a un Web Worker y el INP baja de 600 ms a 120 ms. ¿Cuánto ha mejorado el LCP? Prácticamente nada, porque ese cálculo ocurría después del pintado.

El corolario práctico es incómodo pero liberador: no existe “optimizar el rendimiento” como tarea única. Existe optimizar una fase concreta identificada por datos. Un equipo que dedica un trimestre a reducir el bundle porque “hay que ir más rápido”, cuando su problema real es que un tercero inyecta un iframe que provoca un CLS de 0,4, ha desperdiciado un trimestre.

ℹ️
La estabilidad es la fase que más se subestima

De las tres, el CLS es la que menos atención recibe y la que produce quejas más viscerales de los usuarios, porque el fallo no es “es lento” sino “he pulsado donde no quería”. Un salto de layout que mueve el botón de confirmar justo cuando el dedo baja convierte un cancelar en un comprar. Y a diferencia de las otras dos fases, casi siempre se arregla con cambios baratos y locales: declarar width y height, reservar el hueco del banner, elegir bien los descriptores de la fuente de respaldo.

Dónde vive cada métrica y qué no ve

Las tres Core Web Vitals cubren una fase cada una, lo cual es elegante y también su limitación: entre las tres queda territorio sin medir.

  • LCP cubre carga, pero solo mide cuándo aparece el elemento más grande. No dice si lo que apareció es útil ni si el resto de la página tardó diez segundos más.
  • INP cubre interacción, pero solo observa clic, toque y pulsación de tecla. El scroll, el hover y el zoom quedan fuera. Una página con un scroll a tirones tiene un INP impecable.
  • CLS cubre estabilidad, pero excluye los desplazamientos ocurridos en los 500 ms siguientes a una entrada discreta del usuario, y no captura desplazamientos que no cambian la posición inicial de un elemento visible.

Además, ninguna de las tres mide la fluidez de las animaciones, la transición entre vistas de una aplicación de una sola página, el consumo de memoria, ni el tiempo hasta que un formulario está realmente operativo. Esas zonas ciegas son reales y se tratan más adelante en el track; conviene saber desde el principio que existen para no confundir “las tres en verde” con “el sitio va bien”.

El síntoma que describe el usuario casi nunca nombra la fase correcta

Cuando alguien de negocio dice “la web va lenta”, lo que ha vivido puede ser cualquiera de las tres cosas, y la palabra que usa no lo distingue. He aprendido a hacer siempre la misma pregunta antes de mirar un solo dato: “¿lento al abrirla, o lento al usarla?”. Esa pregunta divide el espacio de búsqueda por la mitad en diez segundos. La segunda pregunta es “¿se te ha movido algo debajo del dedo?”, que caza el CLS, que la gente nunca describe como lentitud sino como “la web hace cosas raras”. Y la tercera, cuando la respuesta es “lento al usarla”, es “¿la primera vez que pulsas o siempre?”: si es solo la primera, el problema es que la interacción coincidió con la hidratación y estás ante un problema de carga disfrazado de interacción. Tres preguntas, treinta segundos, y llegas a los datos sabiendo dónde mirar.

De síntoma a fase

Este es el mapa de traducción que conviene tener interiorizado desde el primer día.

  • “Se queda en blanco un buen rato” — carga. Mira TTFB primero; si es alto, el problema es servidor o red antes de que el navegador haga nada.
  • “Aparece el texto pero la imagen tarda” — carga, subparte de recurso. El elemento LCP probablemente es esa imagen y se descubre tarde.
  • “Pulso y no pasa nada, luego pasa todo de golpe” — interacción. El hilo principal estaba bloqueado y los eventos se encolaron.
  • “Escribo en el buscador y va a trompicones” — interacción, con trabajo síncrono por pulsación.
  • “Me ha cambiado el sitio el botón” — estabilidad.
  • “Va bien en mi ordenador pero mi madre dice que no” — cualquiera de las tres, pero mira primero CPU del dispositivo y red: es el patrón clásico de un problema que solo existe en gama media.
  • “Al principio va lento y luego bien” — interacción durante la carga. El caso más difícil, porque las dos fases se solapan y hay que mirar el loadState de la interacción.

Cada una de esas entradas se convierte en un nivel del track. La siguiente lección desarrolla la cadena física completa que hay detrás de la fase de carga, porque es la que más pasos encadena y la que más gente da por sabida sin saberla.