Observador de rendimiento: Acceso eficiente a los datos de rendimiento

Las apps web progresivas permiten a los desarrolladores compilar una nueva clase de aplicaciones que brindan experiencias del usuario confiables y de alto rendimiento. Sin embargo, para asegurarse de que una aplicación web logre sus objetivos de rendimiento deseados, los desarrolladores necesitan acceso a datos de medición de rendimiento de alta resolución. La especificación del cronograma de rendimiento de W3C define esta interfaz para que los navegadores proporcionen acceso programático a los datos de tiempo de bajo nivel. Esto abre la puerta a algunos casos de uso interesantes:

  • análisis de rendimiento sin conexión y personalizados
  • herramientas externas de análisis y visualización de rendimiento
  • Evaluación de rendimiento integrada en IDE y otras herramientas para desarrolladores

El acceso a este tipo de datos de tiempo ya está disponible en la mayoría de los navegadores principales para la sincronización de la navegación, la sincronización de recursos y la sincronización del usuario. La incorporación más reciente es la interfaz de performance Observer, que es básicamente una interfaz de transmisión que permite recopilar información de tiempo de bajo nivel de manera asíncrona, a medida que el navegador la recopila. Esta nueva interfaz proporciona una serie de ventajas críticas sobre los métodos anteriores para acceder al cronograma:

  • En la actualidad, las apps tienen que sondear y diferenciar periódicamente las mediciones almacenadas, lo que es costoso. Esta interfaz les ofrece una devolución de llamada. (En otras palabras, no es necesario sondear). Como resultado, las apps que usan esta API pueden ser más responsivas y eficientes.
  • No está sujeto a los límites de búfer (la mayoría de los búferes están configurados en 150 elementos de forma predeterminada) y evita las condiciones de carrera entre diferentes consumidores que podrían querer modificar el búfer.
  • Las notificaciones de observador de rendimiento se entregan de forma asíncrona y el navegador puede despacharlas durante el tiempo de inactividad para evitar competir con el trabajo de renderización crítica.

A partir de Chrome 52, la interfaz del observador de rendimiento está habilitada de forma predeterminada. Veamos cómo se usa.

<html>
<head>
    <script>
    var observer = new PerformanceObserver(list => {
        list.getEntries().forEach(entry => {
        // Display each reported measurement on console
        if (console) {
            console.log("Name: "       + entry.name      +
                        ", Type: "     + entry.entryType +
                        ", Start: "    + entry.startTime +
                        ", Duration: " + entry.duration  + "\n");
        }
        })
    });
    observer.observe({entryTypes: ['resource', 'mark', 'measure']});
    performance.mark('registered-observer');

    function clicked(elem) {
        performance.measure('button clicked');
    }
    </script>
</head>
<body>
    <button onclick="clicked(this)">Measure</button>
</body>
</html>

Esta página sencilla comienza con una etiqueta de secuencia de comandos que define código de JavaScript:

  • Creamos una instancia de un objeto PerformanceObserver nuevo y pasamos una función de controlador de eventos al constructor del objeto. El constructor inicializa el objeto de manera que se llame a nuestro controlador cada vez que un conjunto nuevo de datos de medición esté listo para procesarse (con los datos de medición pasados como una lista de objetos). El controlador se define aquí como una función anónima que simplemente muestra los datos de medición con formato en la consola. En una situación real, estos datos pueden almacenarse en la nube para su posterior análisis o canalizarse a una herramienta de visualización interactiva.
  • Mediante el método observe(), nos registramos para los tipos de eventos de tiempo que nos interesan y llamamos al método mark() para marcar el momento en el que nos registramos, que consideraremos el comienzo de nuestros intervalos de tiempo.
  • Se define un controlador de clics para un botón definido en el cuerpo de la página. Este controlador de clics llama al método measure() para capturar datos de latencia sobre cuándo se hizo clic en el botón.

En el cuerpo de la página, definimos un botón y asignamos nuestro controlador de clics al evento onclick. Ya está todo listo.

Ahora, si cargamos la página y abrimos el panel de las Herramientas para desarrolladores de Chrome para mirar la Consola de JavaScript, cada vez que hacemos clic en el botón, se realiza una medición de rendimiento. Y, como nos registramos para observar esas mediciones, se reenvían a nuestro controlador de eventos de forma asíncrona sin necesidad de sondear el cronograma, que muestra las mediciones en la consola a medida que ocurren:

Observador de rendimiento

El valor start representa la marca de tiempo de inicio para eventos de tipo mark (de los cuales esta app solo tiene uno). Los eventos de tipo measure no tienen una hora de inicio inherente, sino que representan las mediciones de tiempo tomadas en relación con el último evento mark. Por lo tanto, los valores de duración que se ven aquí representan el tiempo transcurrido entre la llamada a mark(), que funciona como un punto de partida de intervalo común, y varias llamadas posteriores a measure().

Como puedes ver, esta API es bastante simple y ofrece la capacidad de recopilar datos de rendimiento filtrados y de alta resolución en tiempo real sin sondeo, lo que debería abrir la puerta a herramientas de rendimiento más eficientes para las aplicaciones web.