Conoce el estado de tu código con la API de ReportingObserver

Encuentra APIs obsoletas en tus apps de producción.

ReportingObserver te permite saber cuándo tu sitio usa una API obsoleta o se encuentra con una intervención del navegador. La funcionalidad básica se lanzó originalmente en Chrome 69. A partir de Chrome 84, se puede usar en trabajadores.

const observer = new ReportingObserver((reports, observer) => {
  for (const report of reports) {
    console.log(report.type, report.url, report.body);
  }
}, {buffered: true});

observer.observe();

Usa la devolución de llamada para enviar informes a un proveedor de backend o de estadísticas para su análisis.

¿Por qué es útil? Antes de esta API, las advertencias de baja y de intervención solo estaban disponibles en las Herramientas para desarrolladores como mensajes de la consola. En particular, las intervenciones solo se activan por varias restricciones del mundo real, como las condiciones del dispositivo y de la red. Por lo tanto, es posible que nunca veas estos mensajes cuando desarrolles o pruebes un sitio de forma local. ReportingObserver proporciona una solución a este problema. Cuando los usuarios experimentan posibles problemas en el entorno real, se puede notificar a los desarrolladores web sobre ellos.

Fondo

Hace un tiempo, escribí una entrada de blog (Observing your web app) porque me pareció fascinante la cantidad de APIs que existen para supervisar las "cosas" que suceden en una app web. Por ejemplo, hay APIs que pueden observar información sobre el DOM: ResizeObserver, IntersectionObserver, MutationObserver. PerformanceObserver captura mediciones de rendimiento. Y los métodos como window.onerror y window.onunhandledrejection incluso nos permiten saber cuándo algo sale mal.

Sin embargo, existen otros tipos de advertencias que no capturan las APIs existentes. Cuando tu sitio usa una API obsoleta o se enfrenta a una intervención del navegador, las Herramientas para desarrolladores son las primeras en informarte al respecto:

Advertencias de la consola de Herramientas para desarrolladores sobre bajas y cambios de comportamiento
Advertencias iniciadas por el navegador en la consola de Herramientas para desarrolladores.

Uno pensaría que window.onerror captura estas advertencias de forma natural. No, en absoluto. Esto se debe a que window.onerror no se activa para las advertencias que genera directamente el usuario-agente. Se activa para los errores de tiempo de ejecución (excepciones de JavaScript y errores de sintaxis) causados por la ejecución de código.

ReportingObserver se encarga de lo que falta. Proporciona una forma programática de recibir notificaciones sobre las advertencias emitidas por el navegador, como las bajas y las intervenciones. Puedes usarla como herramienta de informes y dormir con más tranquilidad, sin preocuparte por si los usuarios tienen problemas inesperados en tu sitio publicado.

La API

ReportingObserver no es diferente de las otras APIs de Observer, como IntersectionObserver y ResizeObserver. Le proporcionas una devolución de llamada y te brinda información. La información que recibe la devolución de llamada es una lista de problemas que causó la página:

const observer = new ReportingObserver((reports, observer) => {
  for (const report of reports) {
    // → report.type === 'deprecation'
    // → report.url === 'https://reporting-observer-api-demo.glitch.me'
    // → report.body.id === 'XMLHttpRequestSynchronousInNonWorkerOutsideBeforeUnload'
    // → report.body.message === 'Synchronous XMLHttpRequest is deprecated...'
    // → report.body.lineNumber === 11
    // → report.body.columnNumber === 22
    // → report.body.sourceFile === 'https://reporting-observer-api-demo.glitch.me'
    // → report.body.anticipatedRemoval === <JS_DATE_STR> or null
  }
});

observer.observe();

Informes filtrados

Los informes se pueden prefiltrar para observar solo ciertos tipos de informes. Ahora mismo, hay dos tipos de informes: 'deprecation' y 'intervention'.

const observer = new ReportingObserver((reports, observer) => {
  …
}, {types: ['deprecation']});

Informes almacenados en búfer

Usa la opción buffered: true cuando quieras ver los informes que se generaron antes de que se creara la instancia de observador:

const observer = new ReportingObserver((reports, observer) => {
  …
}, {types: ['intervention'], buffered: true});

Esta opción es ideal para situaciones como la carga diferida de una biblioteca que usa un ReportingObserver. El observador se agrega tarde, pero no te pierdes nada de lo que sucedió antes en la carga de la página.

Detener la observación

Detén la observación con el método disconnect():

observer.disconnect();

Ejemplos

Informa las intervenciones del navegador a un proveedor de estadísticas

const observer = new ReportingObserver((reports, observer) => {
  for (const report of reports) {
    sendReportToAnalytics(JSON.stringify(report.body));
  }
}, {types: ['intervention'], buffered: true});

observer.observe();

Recibir notificaciones cuando se vayan a quitar las APIs

const observer = new ReportingObserver((reports, observer) => {
  for (const report of reports) {
    if (report.type === 'deprecation') {
      sendToBackend(`Using a deprecated API in ${report.body.sourceFile} which will be
                     removed on ${report.body.anticipatedRemoval}. Info: ${report.body.message}`);
    }
  }
});

observer.observe();

Conclusión

ReportingObserver te brinda una forma adicional de descubrir y supervisar posibles problemas en tu app web. Incluso es una herramienta útil para comprender el estado de tu base de código (o la falta de este). Envía informes a un backend, conoce los problemas del mundo real, actualiza el código y obtén beneficios.

Trabajo futuro

En el futuro, esperamos que ReportingObserver se convierta en la API de facto para detectar todo tipo de problemas en JavaScript. Imagina una API que detecte todo lo que sale mal en tu app:

Recursos adicionales:

Imagen hero de Sieuwert Otterloo en Unsplash.