Grabar un perfil limpio: todo lo que va antes de pulsar el botón
Las siete decisiones que se toman antes de empezar a grabar y que deciden si el perfil resultante es legible o es ruido, con el guion de grabación para cada tipo de problema.
Un perfil de rendimiento es un volcado de todo lo que hizo el navegador durante unos segundos, con resolución de microsegundos y decenas de miles de eventos. Si esos segundos contienen la carga de la página, tres interacciones tuyas, una extensión inyectando código y el propio movimiento del ratón buscando el botón de parar, el resultado es ilegible: no porque falte información, sino porque sobra. La diferencia entre un perfil que se lee en dos minutos y uno que no se lee nunca se decide entera antes de empezar a grabar.
- Preparar el entorno para que el perfil mida la aplicación y no el entorno de desarrollo.
- Elegir la ralentización de CPU y de red que corresponde al escenario que se investiga.
- Aplicar el guion de grabación adecuado a cada uno de los tres tipos de problema.
- Marcar el perfil desde el propio código para no depender de la memoria al leerlo.
Las siete decisiones previas
Ventana limpia. Una ventana de incógnito, sin extensiones. Las extensiones inyectan scripts que se ejecutan en el hilo principal de tu página y aparecen en el perfil mezclados con tu código. Un bloqueador de anuncios activo puede añadir decenas de milisegundos de trabajo por carga que no existen en la máquina de nadie más. Esta decisión sola elimina la mitad del ruido.
Sin las DevTools acopladas al lado si mides layout. El acoplamiento lateral cambia el ancho de la ventana y por tanto las media queries y los cálculos de disposición. Para medir, desacopla en ventana propia o mide con las dimensiones que vayas a documentar.
Ralentización de CPU decidida a conciencia. Sin ralentización mides tu portátil, y tu portátil no es el dispositivo de nadie. La ralentización correcta depende de a quién quieras representar, y en cualquier caso el número tiene que quedar anotado junto al perfil, porque dos perfiles con ralentizaciones distintas no se pueden comparar. Las versiones recientes permiten calibrar los preajustes de gama media y gama baja contra tu propia máquina, lo que hace el número mucho más significativo que un multiplicador arbitrario.
Ralentización de red según el escenario. Para un problema de interacción, ninguna: la red no participa y solo añadiría espera. Para un problema de carga, la del usuario objetivo. Ese detalle se trató en el throttling de red.
Caché en el estado que corresponde. Una carga en frío y una carga en caliente son dos escenarios distintos con dos perfiles distintos. Decide cuál mides y sé consistente.
El escenario ensayado. Antes de grabar, haz el recorrido una vez sin grabar. Así el perfil no contiene tus dudas, tu búsqueda del botón ni el desplazamiento hasta encontrarlo.
Duración objetivo por debajo de veinte segundos. Por encima de eso, el propio panel tarda en procesar, la línea de tiempo se vuelve difícil de navegar y la probabilidad de haber capturado dos problemas mezclados crece. Si el escenario necesita más, divídelo.
Grabar el arranque con el botón normal es un error de método frecuente: cuando pulsas, la página ya lleva cargada un rato. Para medir la carga hay que usar la acción específica que recarga y graba desde el primer instante. Es una acción distinta, con su propio botón y su propia entrada en el menú de comandos, y sin ella el perfil empieza tarde y le falta precisamente la parte que ibas a investigar.
Los tres guiones
Cada tipo de problema tiene un guion de grabación distinto, y usar el equivocado produce un perfil que técnicamente contiene el problema pero en el que no se ve.
Problema de carga. Recarga con grabación desde el principio, con la red y la CPU del usuario objetivo, con la caché vacía si mides primera visita. Deja de grabar unos segundos después de que la página se vea estable. No interactúes durante la grabación: cualquier clic añade trabajo que se mezcla con el de arranque.
Problema de interacción. Carga la página, espera a que se calme del todo, empieza a grabar, haz la interacción una sola vez, para. El perfil debería durar dos o tres segundos. La red no interviene salvo que la interacción dispare una petición, y en ese caso lo que mides es la respuesta de la interfaz, no la de la red. La tentación de repetir la interacción cinco veces “para asegurarse” produce un perfil cinco veces más largo en el que hay que comparar cinco bloques; es mejor grabar cinco perfiles cortos.
Problema de animación o de desplazamiento. Empieza a grabar, ejecuta el movimiento de forma sostenida y regular durante tres o cuatro segundos, para. Aquí la regularidad importa: un desplazamiento a tirones produce un perfil con huecos que parecen fotogramas perdidos y no lo son.
Marcar el perfil desde el código
Un perfil sin marcas obliga a reconstruir de memoria qué estaba pasando en cada tramo. Las marcas de usuario aparecen en su propia pista y convierten el perfil en algo navegable.
// Instrumentacion minima que aparece en el perfil
performance.mark('carrito:abrir');
// ... trabajo real ...
performance.mark('carrito:pintado');
performance.measure('Abrir carrito', 'carrito:abrir', 'carrito:pintado');
Las versiones recientes del panel permiten además crear pistas propias desde el código, lo que separa tu instrumentación del ruido del navegador. Se hace pasando un objeto detail con una clave reservada:
// Una medida que aparece en una pista propia del panel de rendimiento
function medirEnPistaPropia(nombre, pista, inicio, fin, color = 'primary') {
performance.measure(nombre, {
start: inicio,
end: fin,
detail: {
devtools: {
dataType: 'track-entry',
track: pista,
color,
properties: [['duracion aproximada', Math.round(fin - inicio) + ' ms']]
}
}
});
}
// Uso: envuelve cualquier trabajo que quieras ver separado
async function conMedida(nombre, pista, fn) {
const t0 = performance.now();
try { return await fn(); }
finally { medirEnPistaPropia(nombre, pista, t0, performance.now()); }
}
// Ejemplo ejecutable
await conMedida('Hidratar lista', 'Mi aplicacion', async () => {
const t = performance.now();
while (performance.now() - t < 40) { /* trabajo simulado */ }
});
Los colores admitidos son un conjunto cerrado con nombres semánticos —primario, secundario, terciario, error, aviso, con variantes clara y oscura— en lugar de valores libres, precisamente para que las pistas propias se integren con la paleta del panel. Y el mismo mecanismo admite marcadores puntuales además de intervalos, cambiando el tipo de dato.
Esta instrumentación tiene una propiedad valiosa: es código de producción legítimo. Las llamadas a la API de rendimiento cuestan microsegundos, no requieren que las DevTools estén abiertas, y las mismas medidas que ves en el perfil las puede recoger un observador y enviarlas a tu sistema de métricas. Instrumentar una vez sirve para el laboratorio y para el campo.
Comprobar que el perfil sirve antes de analizarlo
Antes de invertir veinte minutos leyendo un perfil, treinta segundos de comprobación evitan analizar basura.
Mira si el problema está ahí. Si investigas un tirón y en la pista de fotogramas no hay ningún fotograma largo, no lo has capturado: repite. Es sorprendentemente frecuente grabar el momento equivocado y después construir una teoría entera sobre un perfil que no contiene el fenómeno.
Mira si hay una sola cosa ahí. Un perfil con la carga y una interacción mezcladas invita a atribuir a la interacción trabajo que era de la carga.
Mira si el orden de magnitud es coherente con la queja. Si el usuario dice que tarda dos segundos y tu perfil muestra ciento veinte milisegundos de trabajo, no estás midiendo lo que él sufre: te falta ralentización, te falta el estado de sus datos, o el problema está en la red y no en el hilo principal.
Y guarda los perfiles que importan. El panel permite exportarlos a fichero y volver a cargarlos. Un perfil de antes de una optimización, guardado, es la única forma honesta de demostrar que la optimización sirvió.
Casi todo el mundo graba un perfil cuando algo va mal y ninguno cuando algo va bien, y eso convierte el análisis en un ejercicio de interpretación en vez de en una comparación. Un perfil aislado plantea una pregunta que no tiene respuesta objetiva: ¿ochenta milisegundos de recálculo de estilo son muchos? Depende de cuántos elementos hay, de qué CPU, de si esa cifra es normal en esta aplicación o es diez veces lo habitual. Sin una referencia, cada número del perfil se juzga con intuición, y la intuición sobre rendimiento es notoriamente mala: la gente optimiza lo que le llama la atención en vez de lo que domina el tiempo. La práctica que resuelve esto es tomar siempre dos perfiles, y elegir bien el segundo. Si investigas una interacción lenta, graba también la misma interacción en una versión donde no lo sea: la de hace tres meses, la de otro entorno, la misma pantalla con diez filas en lugar de mil, o la misma acción en un competidor. Si investigas una regresión, el perfil de la versión anterior es el patrón oro y merece la pena reconstruirlo aunque cueste veinte minutos de despliegue. Si no hay ninguna versión buena porque el problema siempre estuvo ahí, entonces el segundo perfil es el mismo escenario con la mitad de los datos: si el tiempo se reduce a la mitad, el coste es lineal en el volumen y sabes dónde mirar; si no se mueve, el coste es fijo y está en otro sitio. Esa comparación convierte cada número en un delta, y un delta sí se interpreta: cuarenta milisegundos que antes eran cuatro son una regresión de diez veces y no admiten discusión. Además hay un beneficio secundario que se nota a los pocos meses: los perfiles guardados de una aplicación forman un histórico, y ese histórico responde en segundos preguntas que de otra forma cuestan un día entero, como cuándo empezó exactamente a tardar el arranque.