Reportingosservazione: conoscere l'integrità del codice

TL;DR

C'è un nuovo osservatore in città. ReportingObserver è una nuova API che ti consente di sapere quando il tuo sito utilizza un'API deprecata o si verifica un intervento del browser:

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

observer.observe();

Il callout può essere utilizzato per inviare report a un backend o a un fornitore di servizi di analisi per ulteriori analisi.

Perché è utile? Fino a questo momento, gli avvisi di ritiro e intervento erano disponibili solo in DevTools come messaggi della console. Gli interventi, in particolare, sono attivati solo da vari vincoli del mondo reale, come le condizioni del dispositivo e della rete. Di conseguenza, potresti non vedere mai questi messaggi quando sviluppi/testi un sito localmente. ReportingObserver fornisce la soluzione a questo problema. Quando gli utenti riscontrano potenziali problemi possiamo ricevere una notifica al riguardo.

Introduzione

Qualche tempo fa ho scritto un post del blog ("Osservare l'app web") perché mi ha affascinato il numero di API disponibili per monitorare le "cose" che accadono in un'app web. Ad esempio, esistono API che possono osservare informazioni sul DOM: ResizeObserver, IntersectionObserver, MutationObserver. Esistono API per acquisire misurazioni del rendimento: PerformanceObserver. Altre API come window.onerror e window.onunhandledrejection ci informano persino quando si verifica un problema.

Tuttavia, esistono altri tipi di avvisi che non vengono rilevati da queste API esistenti. Quando il tuo sito utilizza un'API obsoleta o si verifica un intervento del browser, DevTools è il primo a informarti:

Avvisi della console DevTools relativi a ritiri e interventi.
Avvisi avviati dal browser nella console DevTools.

È naturale pensare che window.onerror acquisisca questi avvisi. No. Questo perché window.onerror non viene attivato per gli avvisi generati direttamente dallo user agent stesso. Viene attivato per errori di runtime (eccezioni JS ed errori di sintassi) causati dall'esecuzione del codice.

ReportingObserver si fa carico del problema. Fornisce un modo programmatico per ricevere notifiche relative agli avvisi emessi dal browser, come ritirazioni e interventi. Puoi utilizzarlo come strumento di generazione di report e non preoccuparti più se gli utenti riscontrano problemi imprevisti sul tuo sito live.

L'API

L'API non è diversa dalle altre API "osservatore" come IntersectionObserver e ResizeObserver. Gli viene chiesto di richiamare, per avere informazioni. Le informazioni ricevute dal callback sono un elenco dei problemi causati dalla pagina:

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();

Report filtrati

Puoi applicare un pre-filtro ai report per osservare solo determinati tipi di report:

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

Report di cui è stato eseguito il buffer

L'opzione buffered: true è molto utile se vuoi visualizzare i report generati prima della creazione dell'osservatore:

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

È ideale per situazioni come il caricamento differito di una libreria che utilizza un ReportingObserver. L'osservatore viene aggiunto in ritardo, ma non perdi nulla di ciò che è accaduto in precedenza durante il caricamento della pagina.

Smetti di osservare

Esatto. È presente un metodo disconnect:

observer.disconnect(); // Stop the observer from collecting reports.

Esempi

Esempio: segnala gli interventi sul browser a un fornitore di servizi di analisi:

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

observer.observe();

Esempio: ricevi una notifica quando le API stanno per essere rimosse:

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();

Conclusione

ReportingObserver ti offre un modo aggiuntivo per scoprire e monitorare potenziali problemi nella tua app web. È anche uno strumento utile per comprendere lo stato della base di codice (o la sua assenza). Invia i report a un backend, scopri i problemi reali riscontrati dagli utenti sul tuo sito, aggiornate il codice e guadagna.

Lavoro futuro

In futuro, spero che ReportingObserver diventi l'API di fatto per rilevare tutti i tipi di problemi in JS. Immagina un'API per rilevare tutto quanto non va nella tua app:

Sono entusiasta anche degli strumenti che integrano ReportingObserver nei loro flussi di lavoro. Lighthouse è un esempio di strumento che segnala già il ritiro delle API del browser quando esegui il suo controllo "Evita API ritirate":

Il controllo Lighthouse per l&#39;utilizzo di API obsolete potrebbe utilizzare ReportingObserver.
Il controllo di Lighthouse per l'utilizzo di API deprecate potrebbe utilizzare ReportingObserver.

Al momento Lighthouse utilizza il protocollo DevTools per eseguire lo scraping dei messaggi della console e segnalare questi problemi agli sviluppatori. Potrebbe invece essere interessante passare a ReportingObserver per i report di ritiro ben strutturati e i metadati aggiuntivi come la data anticipatedRemoval.

Risorse aggiuntive: