Los frameworks web, como Angular, React, Vue y Svelte, facilitan la escritura y el mantenimiento de aplicaciones web complejas a gran escala.
Sin embargo, estos frameworks introducen una capa de abstracción sobre el modelo de aplicación del navegador. De hecho, el código que escriben los desarrolladores que usan estas abstracciones suele transpilarse en código ilegible, minimizado y agrupado. Como consecuencia, aprovechar al máximo el poder de DevTools para depurar y generar perfiles de estas apps puede ser un desafío para los desarrolladores.
Por ejemplo, cuando se genera un perfil de una aplicación de Angular con el panel Rendimiento en las Herramientas para desarrolladores, verás lo siguiente:

Con la información presentada de esta manera, puede ser difícil determinar qué cuellos de botella de rendimiento existen en tu base de código. Después de todo, le falta el contexto de las construcciones del framework y una buena parte de la información que se muestra está en términos de código minimizado. También es difícil distinguir entre la actividad relacionada directamente con el código que escribiste, los elementos internos del framework y otro código de terceros que podría ejecutarse en la misma página.
Una motivación común para los autores de frameworks y abstracciones es implementar sus propias extensiones de DevTools que presenten los datos de generación de perfiles en términos de los conceptos del framework. Estas herramientas son muy útiles cuando se depuran y se generan perfiles de aplicaciones compiladas con un framework específico. Sin embargo, a menudo necesitarás correlacionar los datos del framework en el propio generador de perfiles del framework con la información del tiempo de ejecución del navegador en el panel Rendimiento de las Herramientas para desarrolladores. Tener estas dos fuentes de datos presentadas por separado en herramientas independientes dificulta la detección y la corrección de los embotellamientos, especialmente a medida que la aplicación se vuelve más compleja. Este es un ejemplo de una visualización de perfil en el generador de perfiles de Angular DevTools:

En un mundo ideal, los desarrolladores tendrían una vista en la que las dos fuentes de datos se mostrarían juntas en el mismo contexto asignado a la misma línea de tiempo.
Por este motivo, colaboramos con el equipo de Angular para incorporar datos de tiempo de ejecución de Angular directamente en el panel Rendimiento con la API de extensibilidad del panel Rendimiento. En esta publicación, analizaremos qué puede hacer la API y cómo se usó en el framework de Angular para lograrlo. La implementación puede servir como ejemplo para otros frameworks y abstracciones que buscan mejorar su experiencia del desarrollador instrumentando sus propias herramientas y ayudando a los desarrolladores que usan las Herramientas para desarrolladores de Chrome.
¿Qué es la API de extensibilidad del panel Rendimiento?
La API te permite agregar tus propias entradas de tiempo al registro del panel Rendimiento, dentro de la misma línea de tiempo que el resto de los datos del navegador. Existen dos mecanismos que te permiten hacerlo:
- La API de User Timing
- La API de
console.timeStamp
La API de User Timing
Puedes usar performance.mark
y performance.measure
para agregar las entradas de la siguiente manera:
// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();
// ... later in your code
performance.measure("Component rendering", {
start: renderStart,
detail: {
devtools: {
dataType: "track-entry",
track: "Components",
color: "secondary",
properties: [
["Render reason", "Props changed"],
["Priority", "low"]
],
}
}
});
Esto hará que se agregue la pista Components a tu línea de tiempo con la medición:

Esta API te permite agregar las entradas al búfer de la línea de tiempo de rendimiento y mostrarlas en la IU del panel Rendimiento de DevTools.
Obtén más información sobre esta API y el objeto devtools
en la documentación.
La API de console.timeStamp
Esta API es una alternativa liviana a la API de User Timing. Con el mismo ejemplo anterior, podrías tener lo siguiente:
// Mark used to represent the start of some activity you want to measure.
// In this case, the rendering of a component.
const renderStart = performance.now();
// ... later in your code
console.timeStamp(
"Component rendering",
/* start time */ renderStart,
/* end time (current time) */ undefined,
/* track name */ "Components",
/* track group name */ undefined,
/* color */ "secondary"
);
Esta API proporciona un método de alto rendimiento para instrumentar aplicaciones: a diferencia de la alternativa de la API de User Timing, no crea datos almacenados en búfer. Esta API solo agrega datos al panel **Rendimiento** en Herramientas para desarrolladores, lo que significa que, cuando Herramientas para desarrolladores no está grabando un registro, las llamadas a la API no realizan ninguna operación (no hacen nada), lo que la hace significativamente más rápida y adecuada para las rutas de acceso activas sensibles al rendimiento. La elección de usar argumentos posicionales en lugar de un objeto que contenga todos los parámetros de personalización también tiene el propósito de mantener la API lo más ligera posible.
Obtén más información para usar console.timeStamp y extender el panel Rendimiento, así como los parámetros que puedes pasar en la documentación.
Cómo Angular integró la API de extensibilidad de DevTools
Analizaremos cómo el equipo de Angular usó la API de extensibilidad para integrarse en las Herramientas para desarrolladores de Chrome.
Evita la sobrecarga con console.timestamp
La instrumentación de Angular con la API de extensibilidad del panel Performance está disponible a partir de la versión 20. El nivel de detalle deseado para los datos de rendimiento en DevTools requiere una API rápida, por lo que la solicitud de extracción (60217) que agregó la instrumentación optó por usar la API de console.timeStamp
. Esto evita que el rendimiento del tiempo de ejecución de la aplicación se vea afectado por la posible sobrecarga de la API de generación de perfiles.
Datos instrumentados
Para proporcionar una buena imagen de qué código de Angular se está ejecutando y por qué se está ejecutando, se instrumentan varias partes de las canalizaciones de inicio y renderización, incluidas las siguientes:
- Arranque de la aplicación y los componentes
- Creación y actualización de componentes
- Ejecución de objetos de escucha de eventos y hooks de ciclo de vida
- Muchas otras (por ejemplo, la creación de componentes dinámicos y la renderización de bloques diferida).
Programación de color
El código de color se usa para indicarle al desarrollador la categoría en la que se incluye una determinada entrada de medición. Por ejemplo, los colores que se usan para las entradas que marcan la ejecución del código de TypeScript creado por el desarrollador son distintos de los colores que se usan para el código producido por el compilador de Angular.
En la siguiente captura de pantalla, puedes ver cómo esto genera puntos de entrada (como la detección de cambios y el procesamiento de componentes) en azul, código generado en púrpura y código de TypeScript (como los hooks y los controladores de eventos) renderizado en verde.

Ten en cuenta que el argumento de color que se pasa a la API no es un valor de color CSS, sino un token semántico que se asigna a un color que coincide con la IU de Herramientas para desarrolladores. Los valores posibles son primary
, secondary
y tertiary,
con sus respectivas variantes -dark
y -light
, así como un color error
.
Pistas
En el momento de escribir este artículo, todos los datos de tiempo de ejecución de Angular se agregan al mismo segmento (etiquetado como "🅰️ Angular"). Sin embargo, es posible agregar varias pistas al registro e incluso agruparlas. Por ejemplo, dadas las siguientes llamadas a la API de console.timeStamp
:
console.timeStamp("Component 1", componentStart1, componentEnd1, "Components", "Client", "primary");
console.timeStamp("Component 2", componentStart2, componentEnd2, "Components", "Client", "primary");
console.timeStamp("Hook 1", hookStart, hookEnd, "Hooks", "Client", "primary");
console.timeStamp("Fetch data base", fetchStart, fetchEnd, "Server", "primary");
Verías los datos organizados en segmentos de la siguiente manera:

Usar pistas separadas puede ser útil, por ejemplo, cuando tienes actividad asíncrona, varios trabajos que se ejecutan en paralelo o simplemente grupos de actividad lo suficientemente distintos como para que valga la pena separarlos en diferentes áreas de la IU.
Por qué esto es importante para los desarrolladores de Angular
El objetivo de esta integración directa es proporcionar una experiencia de análisis del rendimiento más intuitiva y completa. Al mostrar los datos de rendimiento internos de Angular directamente en el panel **Rendimiento**, los desarrolladores obtendrán lo siguiente:
- Visibilidad mejorada: Los eventos de rendimiento específicos de Angular, como la renderización de componentes, los ciclos de detección de cambios y mucho más, se hacen visibles en el cronograma más amplio del navegador.
- Comprensión mejorada: Con información enriquecida en contexto sobre los procesos internos de Angular, lo que te ayuda a identificar los cuellos de botella del rendimiento de manera más eficaz.
Cómo habilitar la integración
El uso de la API de extensibilidad está disponible oficialmente en las compilaciones de desarrollo a partir de la versión 20 de Angular. Para habilitarlo, debes ejecutar la utilidad global `ng.enableProfiling()` en tu app o en la consola de Herramientas para desarrolladores. Obtén más información sobre la integración en la [documentación de Angular](https://angular.dev/best-practices/profiling-with-chrome-devtools).
Otras consideraciones
Algunas consideraciones importantes que se deben tener en cuenta.
Mapas de orígenes y código reducido:
Los mapas de origen son una herramienta ampliamente adoptada que tiene como objetivo cerrar la brecha entre el código agrupado o reducido y su contraparte creada, por lo que…
¿No se supone que los mapas de origen resuelven el problema del código reducido en las apps agrupadas?
Si bien los mapas de origen son útiles, no eliminan por completo los desafíos cuando se perfilan apps web complejas minimizadas. Los mapas de orígenes permiten que DevTools vuelva a asignar el código reducido a tu código fuente original, lo que facilita la depuración. Sin embargo, depender únicamente de los mapas de origen para el análisis del rendimiento puede presentar algunas limitaciones. Por ejemplo, elegir la forma en que los elementos internos del framework y el código creado se separan visualmente es complicado solo con los mapas de fuentes. Por otro lado, la API de extensibilidad proporciona la flexibilidad necesaria para lograr esta distinción y presentarla de la manera que el desarrollador considere más conveniente.
Extensiones de Herramientas para desarrolladores de Chrome:
Las extensiones de Chrome que usan la API de DevTools son una herramienta muy utilizada para extender las herramientas para desarrolladores.
¿Los generadores de perfiles dedicados (por ejemplo, las extensiones de las Herramientas para desarrolladores de Chrome) son innecesarios o están desaconsejados ahora que esta API está disponible?
No, esta API no está diseñada para reemplazar ni desalentar el desarrollo de analizadores dedicados, como las extensiones de Herramientas para desarrolladores de Chrome. Aun así, pueden ofrecer funciones, visualizaciones y flujos de trabajo especializados y adaptados a necesidades específicas. El objetivo de la API de extensibilidad del panel Rendimiento es crear una integración perfecta de los datos personalizados con las visualizaciones del navegador en el panel Rendimiento.
El camino a seguir
Es el prospecto de la API de extensibilidad.
Trabajar con más frameworks y abstracciones
Nos entusiasman otros frameworks y abstracciones que adoptan la API para mejorar la experiencia de generación de perfiles de sus desarrolladores. Por ejemplo, React implementó una adopción experimental de la API para su framework. Esta instrumentación muestra la renderización de componentes del cliente y del servidor, así como los datos de las APIs de programación de React. Obtén más información sobre esta función y cómo habilitarla en la página de React.
Compilaciones de producción
Uno de los objetivos de esta API es trabajar con frameworks y proveedores de abstracción en general para adoptar y habilitar la instrumentación en compilaciones de producción. Esto podría tener un gran impacto en el rendimiento de las apps desarrolladas con estas abstracciones, ya que los desarrolladores podrían crear perfiles de la aplicación tal como la experimentan sus usuarios. Creemos que la API de console.timeStamp
permite lograr esto, dada su velocidad y su baja sobrecarga. Sin embargo, por el momento, los frameworks siguen experimentando con la API y analizando qué tipos de instrumentaciones son más escalables y útiles para los desarrolladores.