Texto longo, leia o resumo
Há um novo observador na cidade! ReportingObserver
é uma nova API que informa
quando o site usa uma API descontinuada ou encontra uma
intervenção do navegador:
const observer = new ReportingObserver(
(reports, observer) => {
for (const report of reports) {
console.log(report.type, report.url, report.body);
}
},
{buffered: true}
);
observer.observe();
O callback pode ser usado para enviar relatórios a um back-end ou provedor de análise para análise posterior.
Por que isso é útil? Até agora, avisos de descontinuação e
intervenção só estavam disponíveis no DevTools como mensagens do console.
As intervenções, em especial, são acionadas apenas por várias restrições do mundo real,
como condições do dispositivo e da rede. Assim, talvez você nem veja essas mensagens
ao desenvolver/testar um site localmente. ReportingObserver
fornece
a solução para esse problema. Quando os usuários enfrentam possíveis problemas,
podemos receber notificações sobre eles.
Introdução
Há algum tempo, escrevi uma postagem no blog ("Observando seu app da Web")
porque achei fascinante a quantidade de APIs para monitorar as
"coisas" que acontecem em um app da Web. Por exemplo, há APIs que podem observar
informações sobre o DOM: ResizeObserver
,
IntersectionObserver
, MutationObserver
. Existem APIs para capturar
medições de performance: PerformanceObserver
. Outras
APIs, como window.onerror
e window.onunhandledrejection
, até informam
quando algo dá errado.
No entanto, há outros tipos de avisos que não são capturados por essas APIs. Quando seu site usa uma API descontinuada ou encontra uma intervenção do navegador, o DevTools informa primeiro:
Naturalmente, você pode pensar que window.onerror
captura esses avisos. Não é.
Isso ocorre porque window.onerror
não é acionado para avisos
gerados diretamente pelo próprio user agent. Ele é disparado em erros de tempo de execução (exceções de JS e erros de sintaxe) causados pela execução do código.
ReportingObserver
assume o controle. Ele oferece uma maneira programática de receber
notificações sobre avisos emitidos pelo navegador, como descontinuações
e intervenções. Você pode usá-lo como uma ferramenta de geração de relatórios e
não se preocupar se os usuários estão enfrentando problemas inesperados no site
ativo.
A API
A API não é diferente das outras APIs "observer", como
IntersectionObserver
e ResizeObserver
. Você fornece um callback;
ele fornece informações. As informações que o callback recebe são uma
lista de problemas que a página causou:
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();
Relatórios filtrados
Os relatórios podem ser pré-filtrados para observar apenas determinados tipos de relatório:
const observer = new ReportingObserver((reports, observer) => {
...
}, {types: ['deprecation']});
Relatórios em buffer
A opção buffered: true
é muito útil quando você quer conferir os relatórios que foram gerados antes da criação do observador:
const observer = new ReportingObserver((reports, observer) => {
...
}, {types: ['intervention'], buffered: true});
É ótimo para situações como o carregamento lento de uma biblioteca que usa
um ReportingObserver
. O observador é adicionado com atraso, mas você
não perde nada que tenha acontecido anteriormente no carregamento da página.
Parar de observar
Sim. Ele tem um método disconnect
:
observer.disconnect(); // Stop the observer from collecting reports.
Exemplos
Exemplo: informe as intervenções do navegador a um provedor de análise:
const observer = new ReportingObserver(
(reports, observer) => {
for (const report of reports) {
sendReportToAnalytics(JSON.stringify(report.body));
}
},
{types: ['intervention'], buffered: true}
);
observer.observe();
Exemplo: receba uma notificação quando as APIs forem removidas:
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();
Conclusão
O ReportingObserver
oferece outra maneira de descobrir e monitorar
possíveis problemas no seu app da Web. Ele é até mesmo uma ferramenta útil para entender a
saúde da sua base de código (ou a falta dela). Envie relatórios para um back-end,
saiba sobre os problemas reais que os usuários estão enfrentando no seu site, atualize
o código e lucre!
Trabalho futuro
No futuro, espero que ReportingObserver
se torne a API padrão
para detectar todos os tipos de problemas no JS. Imagine uma API para detectar tudo
o que dá errado no seu app:
- Intervenções no navegador
- Suspensões de uso
- Violações da política de recursos. Consulte crbug.com/867471.
- Exceções e erros do JS (atualmente atendidos por
window.onerror
). - Rejeições de promessas do JS não tratadas (atualmente atendidas por
window.onunhandledrejection
)
Também estou animado com as ferramentas que integram ReportingObserver
aos
fluxos de trabalho. O Lighthouse é um exemplo de ferramenta
que já sinaliza descontinuações de navegadores quando você executa a
auditoria "Evitar APIs descontinuadas":
Atualmente, o Lighthouse usa o protocolo DevTools
para extrair mensagens do console e informar esses problemas aos desenvolvedores. Em vez disso,
pode ser interessante mudar para ReportingObserver
para relatórios de descontinuação bem estruturados e outros metadados, como
a data anticipatedRemoval
.
Outros recursos: