Command Palette

Search for a command to run...

Performance API: Medir el Rendimiento de Tu Código

Aprende a usar la Performance API de JavaScript para medir con precisión el tiempo de ejecución de tu código, identificar cuellos de botella y optimizar el rendimiento.

Lectura: 18 min
Nivel: Intermedio

TL;DR - Resumen rápido

  • performance.now() proporciona un temporizador de alta precisión para medir duraciones
  • performance.mark() crea marcas de tiempo con nombre para puntos específicos del código
  • performance.measure() calcula la duración entre dos marcas
  • PerformanceObserver permite observar eventos de rendimiento en tiempo real
  • La Performance API es más precisa que Date.now() para mediciones de rendimiento

Introducción a la Performance API

La Performance API es un conjunto de APIs del navegador que te permite medir el rendimiento de tu aplicación web con alta precisión. A diferencia de Date.now(), que tiene una precisión de milisegundos, la Performance API usa un temporizador de alta resolución (sub-milisegundos) que es ideal para mediciones de rendimiento y profiling de código.

La Performance API es especialmente útil para identificar cuellos de botella en tu código, medir el tiempo de ejecución de funciones específicas, y entender cómo se comporta tu aplicación en diferentes dispositivos y condiciones de red. Usar esta API te permite tomar decisiones informadas sobre optimización basadas en datos reales en lugar de suposiciones.

Soporte del Navegador

La Performance API es ampliamente soportada en navegadores modernos, incluyendo Chrome, Firefox, Safari y Edge. Sin embargo, algunas características específicas pueden tener soporte limitado en navegadores más antiguos. Siempre verifica el soporte antes de usar características específicas de la API.

¿Qué es la Performance API?

La Performance API es una interfaz del navegador que proporciona acceso a métricas de rendimiento relacionadas con la navegación, recursos y el tiempo de ejecución de código JavaScript. La API está diseñada para ser de baja sobrecarga, lo que significa que usarla para medir el rendimiento no afecta significativamente el rendimiento que estás midiendo.

La Performance API incluye varios métodos y propiedades, siendo los más importantes performance.now() para mediciones de tiempo, performance.mark() y performance.measure() para crear marcas y mediciones personalizadas, y PerformanceObserver para observar eventos de rendimiento en tiempo real.

  • performance.now() - Retorna el tiempo actual con alta precisión
  • performance.mark() - Crea una marca de tiempo con nombre
  • performance.measure() - Calcula la duración entre dos marcas
  • performance.getEntries() - Obtiene todas las entradas de rendimiento
  • PerformanceObserver - Observa eventos de rendimiento en tiempo real
  • performance.clearMarks() - Limpia todas las marcas
  • performance.clearMeasures() - Limpia todas las mediciones

performance.now()

performance.now() es el método más básico y útil de la Performance API. Retorna el tiempo transcurrido en milisegundos desde el inicio de la navegación actual, con precisión de sub-milisegundos (típicamente microsegundos). A diferencia de Date.now(), que retorna el tiempo desde la época Unix (1 de enero de 1970), performance.now() retorna un valor relativo que es ideal para medir duraciones.

La precisión de performance.now() es mucho mayor que Date.now(), lo que la hace ideal para medir operaciones rápidas que duran menos de un milisegundo. Además, performance.now() es monótono (siempre aumenta), lo que elimina problemas con ajustes de reloj del sistema que pueden afectar a Date.now().

performance-now.js
Loading code...

Este ejemplo muestra cómo usar performance.now() para medir el tiempo de ejecución de una función. La diferencia entre el tiempo final y el tiempo inicial nos da la duración exacta de la ejecución con precisión de microsegundos.

Precisión de performance.now()

performance.now() tiene una precisión típica de 5 microsegundos (0.005ms) en navegadores modernos, lo que es 200 veces más preciso que Date.now() (1ms). Esta precisión es esencial para medir operaciones rápidas y detectar pequeñas diferencias de rendimiento.

performance.mark()

performance.mark() crea una marca de tiempo con nombre en el timeline de rendimiento. Las marcas son útiles para identificar puntos específicos en la ejecución de tu código, como el inicio y fin de una función, o momentos importantes en el flujo de tu aplicación.

Las marcas creadas con performance.mark() se almacenan en el buffer de rendimiento del navegador y pueden ser recuperadas con performance.getEntriesByType('mark'). Las marcas son especialmente útiles cuando se combinan con performance.measure() para calcular duraciones entre puntos específicos.

performance-mark.js
Loading code...

Este ejemplo muestra cómo crear marcas en puntos específicos del código. Las marcas 'start-process' y 'end-process' identifican el inicio y fin del procesamiento, mientras que 'checkpoint-1' identifica un punto intermedio importante.

performance.measure()

performance.measure() calcula la duración entre dos marcas o puntos de tiempo. A diferencia de simplemente restar dos valores de performance.now(), performance.measure() crea una entrada de rendimiento que puede ser recuperada y analizada posteriormente. Esto es especialmente útil para análisis de rendimiento y debugging.

performance.measure() acepta hasta tres parámetros: el nombre de la medición, la marca inicial y la marca final. Si no se especifican marcas, performance.measure() usa el tiempo actual como la marca inicial o final, dependiendo de cuál se omita.

performance-measure.js
Loading code...

Este ejemplo muestra cómo usar performance.measure() para calcular duraciones entre marcas. Las mediciones permiten entender qué partes de tu código consumen más tiempo y dónde enfocarte al optimizar.

performance.getEntries()

performance.getEntries() y sus métodos relacionados te permiten recuperar todas las entradas de rendimiento almacenadas en el buffer del navegador. Esto incluye marcas, mediciones, tiempos de navegación, tiempos de recursos y otros eventos de rendimiento.

Hay varios métodos para recuperar entradas de rendimiento: performance.getEntries() retorna todas las entradas, performance.getEntriesByType() retorna entradas de un tipo específico, y performance.getEntriesByName() retorna entradas con un nombre específico. Estos métodos aceptan filtros adicionales para refinar los resultados.

performance-entries.js
Loading code...

Este ejemplo muestra cómo recuperar diferentes tipos de entradas de rendimiento. performance.getEntriesByType('measure') retorna todas las mediciones, performance.getEntriesByName() retorna entradas con un nombre específico, y performance.getEntries() retorna todas las entradas almacenadas.

PerformanceObserver

PerformanceObserver es una API que te permite observar eventos de rendimiento en tiempo real. A diferencia de performance.getEntries(), que requiere que recuperes las entradas manualmente, PerformanceObserver te notifica automáticamente cuando ocurren nuevos eventos de rendimiento.

PerformanceObserver es especialmente útil para monitoreo continuo de rendimiento, análisis en tiempo real, y para capturar eventos que ocurren después de que tu código ha terminado de ejecutarse. Puedes observar diferentes tipos de eventos como 'measure', 'mark', 'resource', 'navigation', y más.

performance-observer.js
Loading code...

Este ejemplo muestra cómo usar PerformanceObserver para observar eventos de rendimiento en tiempo real. El observer se crea con una lista de tipos de entrada a observar, y el callback se ejecuta cada vez que ocurre un nuevo evento de esos tipos.

Desconectar Observadores

Siempre desconecta PerformanceObserver cuando ya no lo necesites usando el método disconnect(). Los observadores que no se desconectan continúan consumiendo memoria y procesando eventos, lo que puede afectar el rendimiento de tu aplicación.

Ejemplos Prácticos

Veamos ejemplos prácticos de cómo usar la Performance API en situaciones reales. Estos ejemplos muestran patrones comunes que puedes adaptar a tus propias aplicaciones para medir y optimizar el rendimiento.

Medir Tiempo de Ejecución de Función

Este ejemplo muestra cómo crear una función utilitaria que mide automáticamente el tiempo de ejecución de cualquier función. Este patrón es útil para profiling y debugging de código.

measure-function.js
Loading code...

Este ejemplo implementa una función measurePerformance que envuelve cualquier función y mide su tiempo de ejecución automáticamente. La función crea marcas antes y después de ejecutar la función, y crea una medición con el resultado. Este patrón reutilizable es especialmente útil en debugging y profiling.

Medir Operaciones Asíncronas

Este ejemplo muestra cómo medir operaciones asíncronas usando la Performance API. Las operaciones asíncronas requieren un enfoque diferente porque el tiempo de ejecución no es continuo.

measure-async.js
Loading code...

Este ejemplo muestra cómo medir operaciones asíncronas como fetch y setTimeout. La función measureAsyncOperation crea marcas antes y después de la operación asíncrona, y crea una medición cuando la operación completa. Este patrón es esencial para medir el rendimiento de operaciones de red y otras tareas asíncronas.

Medir Operaciones de Red

Para operaciones de red como fetch, también puedes usar el Resource Timing API que proporciona información detallada sobre tiempos de DNS, TCP, TLS, y descarga. Combina esto con performance.measure() para una visión completa del rendimiento de operaciones de red.

Mejores Prácticas

Usar la Performance API efectivamente requiere seguir ciertas mejores prácticas para obtener mediciones precisas y evitar afectar el rendimiento que estás midiendo.

  • Usa performance.now() en lugar de Date.now() para mediciones de alta precisión
  • Limpia marcas y mediciones con clearMarks() y clearMeasures() cuando ya no las necesites
  • Usa PerformanceObserver para monitoreo continuo en lugar de polling manual
  • Crea nombres descriptivos para marcas y mediciones para facilitar el análisis
  • Usa filtros específicos (getEntriesByType, getEntriesByName) en lugar de getEntries()
  • Desconecta PerformanceObserver cuando ya no lo necesites con disconnect()
  • Combina la Performance API con Chrome DevTools para un análisis completo del rendimiento

Performance API en Producción

La Performance API es de baja sobrecarga y segura para usar en producción. Sin embargo, considera agregar lógica para desactivar las mediciones en producción si no las necesitas, o usar sampling para reducir el impacto en el rendimiento. También considera enviar las métricas a un servicio de análisis para monitoreo continuo.

Resumen: Performance API

Conceptos principales:

  • performance.now() proporciona un temporizador de alta precisión para medir duraciones
  • performance.mark() crea marcas de tiempo con nombre para puntos específicos del código
  • performance.measure() calcula la duración entre dos marcas
  • PerformanceObserver permite observar eventos de rendimiento en tiempo real
  • performance.getEntries() recupera todas las entradas de rendimiento almacenadas
  • La Performance API es más precisa que Date.now() para mediciones de rendimiento

Mejores prácticas:

  • Usa performance.now() en lugar de Date.now() para mediciones de alta precisión
  • Limpia marcas y mediciones con clearMarks() y clearMeasures() cuando ya no las necesites
  • Usa PerformanceObserver para monitoreo continuo en lugar de polling manual
  • Crea nombres descriptivos para marcas y mediciones para facilitar el análisis
  • Usa filtros específicos en lugar de getEntries() para mejor rendimiento
  • Desconecta PerformanceObserver cuando ya no lo necesites con disconnect()