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 callback può essere utilizzato per inviare report a un provider di backend o analisi per ulteriori analisi.
Perché è utile? Finora gli avvisi relativi al ritiro e all'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. Potresti quindi non vedere mai questi messaggi
durante lo sviluppo/test di un sito a livello locale. 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 ("Observing your web app")
perché ho scoperto quante API ci sono per monitorare i
"contenuti" che si verificano in un'app web. Ad esempio, esistono API che possono osservare
le informazioni sul DOM: ResizeObserver
,
IntersectionObserver
, MutationObserver
. Esistono delle API per l'acquisizione
delle misurazioni del rendimento: PerformanceObserver
. Altre
API come window.onerror
e window.onunhandledrejection
ci fanno persino sapere
quando qualcosa va storto.
Tuttavia, esistono altri tipi di avvisi che non vengono acquisiti da queste API esistenti. Quando il tuo sito utilizza un'API deprecata o si verifica con un intervento del browser, DevTools comunica prima al riguardo:
Si potrebbe pensare che window.onerror
acquisisca questi avvisi. No.
Questo perché window.onerror
non si attiva per gli avvisi
generati direttamente dallo user agent stesso. Si attiva per errori di runtime (eccezioni JS ed errori di sintassi) causati dall'esecuzione del codice.
ReportingObserver
riprende il gioco. Fornisce un modo programmatico per ricevere notifiche relative ad avvisi emessi dal browser, come rimozioni e interventi. Puoi utilizzarlo come strumento di segnalazione e perdere meno sonno chiedendo agli utenti se stanno riscontrando problemi imprevisti sul tuo sito dal vivo.
L'API
L'API non è diversa dalle altre API "observer"
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
è davvero utile per visualizzare i report generati prima della creazione dell'osservatore:
const observer = new ReportingObserver((reports, observer) => {
...
}, {types: ['intervention'], buffered: true});
È ideale in situazioni come il caricamento lento di una libreria che utilizza
un ReportingObserver
. L'osservatore viene aggiunto in ritardo, ma
non perdi nulla di ciò che è successo in precedenza durante il caricamento pagina.
Smetti di osservare
Esatto. È presente un metodo disconnect
:
observer.disconnect(); // Stop the observer from collecting reports.
Esempi
Esempio - segnala gli interventi del browser a un provider di analisi dati:
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 verranno 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
offre un ulteriore modo per scoprire e monitorare
potenziali problemi nella tua app web. È anche uno strumento utile per comprendere
lo stato del tuo codebase (o la sua mancanza). Invia report a un backend,
scopri i problemi reali riscontrati dagli utenti sul tuo sito, aggiorna
il codice e guadagna.
Lavoro futuro
In futuro, spero che ReportingObserver
diventi l'API di fatto
per la risoluzione di tutti i tipi di problemi in JavaScript. Immagina un'unica API per rilevare
tutti gli errori nella tua app:
- Interventi del browser
- Deprecazioni
- Violazioni delle norme relative alle funzionalità. Visita la pagina crbug.com/867471.
- Eccezioni ed errori JS (attualmente gestito da
window.onerror
). - Rifiuti della promessa JS non gestita (attualmente gestita da
window.onunhandledrejection
)
Sono anche entusiasta degli strumenti che integrano ReportingObserver
nei
suoi flussi di lavoro. Lighthouse è un esempio di strumento
che già segnala i ritiri del browser quando esegui il controllo
"Evita le API deprecate":
Attualmente 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 suoi report sul ritiro ben strutturati e metadati aggiuntivi come
la data del anticipatedRemoval
.
Risorse aggiuntive: