wandres.dev
PERFORMANCE II · Las métricas en vivo

Las métricas dentro del perfil: de la cifra al instante

Cómo aparecen los hitos y las métricas en las pistas del timeline, qué información añade verlas junto al trabajo que las produjo, y cómo se relacionan entre sí.

⏱ 16 min

Una métrica es un número, y un número no se puede arreglar. Lo que se arregla es el trabajo concreto que ocurrió en el instante que ese número señala. La diferencia entre las herramientas que dan métricas y el panel de rendimiento es exactamente esa: aquí la métrica no es una cifra en una tarjeta sino un marcador colocado en una línea de tiempo, con todo lo que estaba pasando debajo. Bajar en vertical desde ese marcador es lo que convierte una métrica en una tarea.

🎯 Al terminar esta lección sabrás
  • Localizar los marcadores de métricas y de hitos dentro de un perfil grabado.
  • Relacionar cada métrica con el trabajo que aparece bajo su marcador.
  • Interpretar los marcadores de salto de disposición y sus elementos responsables.
  • Explicar la relación causal entre las tres métricas principales.

Dónde aparecen

Al grabar una carga de página, la pista de tiempos se llena de marcadores verticales. Los principales son cuatro y conviene distinguirlos porque miden cosas muy distintas.

La primera pintura con contenido marca el instante en que apareció el primer píxel de contenido real. Es la métrica de “ya no está en blanco”.

La pintura de contenido mayor marca cuándo se pintó el elemento principal. Es la métrica de “ya se ve lo que venía a ver”.

El contenido del documento cargado marca cuándo el documento quedó analizado y sus scripts síncronos ejecutados.

La carga marca cuándo terminaron los recursos dependientes. Sigue apareciendo por costumbre histórica y es la que menos correlaciona con la experiencia real, porque una página puede ser perfectamente usable mucho antes o quedarse esperando por un recurso irrelevante mucho después.

Junto a esos hitos aparecen tus propias medidas, si has instrumentado, y en su propia pista los saltos de disposición y las interacciones.

Al seleccionar un marcador, el panel muestra su información asociada. Para la pintura mayor, el elemento concreto. Para un salto, los nodos que se movieron y la puntuación de ese salto. Para una interacción, el desglose de sus fases. Esa información es la que no da ninguna herramienta que se limite a reportar métricas.

El valor de verlas en contexto

La razón de que verlas dentro del perfil sea cualitativamente distinto es que el instante de la métrica está rodeado de causas.

Coloca el cursor sobre el marcador de la pintura mayor y mira hacia atrás en la pista de red: ¿cuándo se pidió el recurso que pinta ese elemento? Si se pidió tarde, la métrica no mejora optimizando nada del elemento, mejora descubriéndolo antes. Mira ahora hacia abajo en el hilo principal: ¿hay una tarea larga justo antes? Entonces el recurso llegó a tiempo y el navegador estaba ocupado y no pudo pintarlo.

Esa pregunta —¿llegó tarde el recurso o llegó a tiempo y no se pintó?— divide el diagnóstico en dos mitades sin nada en común, y se responde en cinco segundos mirando la vertical del marcador. Ninguna cifra agregada la responde.

Lo mismo con los saltos. Un marcador de salto tiene siempre, justo antes, algo que lo causó: una imagen que terminó de descargarse y ocupó su tamaño real, una fuente que se sustituyó, un anuncio que se insertó, un componente que se hidrató y cambió de tamaño. Ese “justo antes” está a la vista en las pistas de red y del hilo principal.

ℹ️
Nota

El elemento que produce la pintura mayor puede cambiar durante la carga y el panel registra el candidato final. Un caso muy frecuente: durante los primeros instantes el candidato es un bloque de texto, y cuando llega la imagen principal pasa a serlo ella. Si optimizas el texto, no cambia nada. El elemento que importa es el que estaba marcado al final, y por eso conviene comprobarlo en el perfil en lugar de suponerlo.

Cómo se relacionan entre sí

Las tres métricas principales parecen independientes y no lo son. Entender la relación evita optimizaciones que mejoran una a costa de otra.

flowchart TB
a[Hilo principal saturado] --> b[Los recursos se descubren tarde]
a --> c[La pintura se retrasa]
b --> c
c --> d[Peor pintura de contenido mayor]
a --> e[Las interacciones esperan]
e --> f[Peor tiempo de respuesta]
g[Contenido que llega tarde y ocupa sitio] --> h[Saltos de disposicion]
d --> i[Percepcion de lentitud al cargar]
f --> j[Percepcion de interfaz rota]
h --> k[Percepcion de descontrol]
style a fill:#f38ba8,color:#11111b
style g fill:#f9e2af,color:#11111b
style d fill:#89b4fa,color:#11111b
style f fill:#89b4fa,color:#11111b
style h fill:#89b4fa,color:#11111b
style i fill:#cba6f7,color:#11111b
style j fill:#cba6f7,color:#11111b
style k fill:#cba6f7,color:#11111b

El nodo del que salen más flechas es el hilo principal saturado, y eso resume la mitad del trabajo de rendimiento web: casi todos los problemas comparten una causa raíz, que es demasiado JavaScript ejecutándose demasiado pronto.

Hay además dos relaciones de compromiso que conviene conocer porque son trampas conocidas.

Mejorar la pintura mayor empeorando los saltos. Mostrar contenido cuanto antes, con reservas de espacio inexistentes o incorrectas, adelanta la pintura y produce movimiento cuando el contenido definitivo llega. La solución no es elegir: es reservar el espacio con las proporciones correctas desde el principio.

Mejorar los saltos empeorando la respuesta. Retrasar la aparición del contenido hasta tenerlo todo evita el movimiento y alarga la espera. Una pantalla que no se mueve porque no muestra nada durante tres segundos no ha mejorado.

Registrar hitos propios

Los hitos estándar describen la carga del documento, no la de tu aplicación. Para una aplicación de una sola página, el instante en el que el usuario puede trabajar puede estar muy lejos de cualquier hito estándar. Marcarlo tú es lo único que hace el perfil legible.

// Hitos de aplicacion que aparecen en la pista de tiempos del perfil
const hito = nombre => {
  performance.mark(nombre);
  // El intervalo desde la navegacion hasta el hito, visible como barra
  performance.measure('hasta ' + nombre, { start: 0, end: performance.now() });
};

// Colocalos en los puntos que definen la experiencia real de tu aplicacion
hito('app:script-ejecutado');

// ... tras montar el armazon de la interfaz
hito('app:armazon-visible');

// ... tras recibir y pintar los datos que el usuario venia a ver
hito('app:datos-pintados');

// ... cuando los manejadores estan puestos y la interfaz responde de verdad
hito('app:interactiva');

// Consulta rapida de todos los hitos registrados
console.table(
  performance.getEntriesByType('mark')
    .filter(m => m.name.startsWith('app:'))
    .map(m => ({ hito: m.name, ms: Math.round(m.startTime) }))
);

El cuarto hito es el que más información añade y el que casi nadie mide: el instante en que la interfaz responde, que en una aplicación hidratada puede estar segundos después de que se vea completa. Ese hueco entre “se ve” y “funciona” es invisible para todas las métricas de carga y es exactamente lo que produce la queja de que la página parecía lista y no hacía nada.

Las métricas estándar miden el documento y tu usuario usa una aplicación

Hay una limitación de fondo en todas las métricas de carga que conviene tener clara antes de invertir semanas en optimizarlas: están definidas sobre la navegación de un documento, y una parte enorme de las aplicaciones modernas hace casi todo su trabajo después de esa navegación. Cuando un usuario pulsa un enlace dentro de una aplicación de una sola página, no hay navegación del documento: hay una petición, un cambio de estado y un repintado. La pintura mayor no se recalcula, los hitos de carga no se disparan, y desde el punto de vista de las métricas estándar no ha pasado nada. Sin embargo, para el usuario ha pasado exactamente lo mismo que en una carga: pidió una pantalla y esperó a verla. Eso significa que una aplicación puede tener métricas de carga excelentes y ser insoportablemente lenta en el noventa por ciento de su uso real, porque solo se mide la primera pantalla y el resto de la sesión es un agujero negro. La corrección tiene dos partes. La primera es instrumentar las transiciones internas como si fueran cargas: marcar el instante en que empieza la navegación interna y el instante en que el contenido destino está pintado, y medir ese intervalo con la misma seriedad con la que se mide la carga inicial. Con las medidas en pistas propias, esas transiciones aparecen en el perfil como bloques nombrados y se analizan con las mismas herramientas. La segunda parte es aceptar que la métrica de respuesta a la interacción es, para este tipo de aplicaciones, mucho más representativa que cualquier métrica de carga, porque es la única de las tres que sigue midiendo durante toda la sesión. Si tuvieras que elegir una sola métrica para vigilar en una aplicación que la gente usa durante minutos u horas, esa es la elección correcta, y sin embargo es la que menos atención recibe porque es la más difícil de mejorar.