通过 ReportingObserver API 了解代码的运行状况

在正式版应用中查找已弃用的 API。

ReportingObserver 会在您的网站使用已废弃的 API 或遇到浏览器干预时通知您。基本功能最初在 Chrome 69 中发布。从 Chrome 84 开始,它可以在 worker 中使用。

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

observer.observe();

使用回调将报告发送到后端或分析服务提供程序进行分析。

这有什么用?在此 API 之前,废弃和干预警告仅以控制台消息的形式在开发者工具中提供。特别是,干预措施仅由设备和网络条件等各种现实约束条件触发。因此,在本地开发/测试网站时,您可能永远不会看到这些消息。ReportingObserver 提供了解决此问题的方法。当用户在实际环境中遇到潜在问题时,Web 开发者可以收到相关通知。

背景

前段时间,我写了一篇博文(监控 Web 应用),因为我发现有许多 API 可用于监控 Web 应用中发生的“事件”。例如,有些 API 可以监控 DOM 相关信息:ResizeObserverIntersectionObserverMutationObserverPerformanceObserver 会捕获性能衡量数据。window.onerrorwindow.onunhandledrejection 等方法甚至会在出现问题时通知我们。

不过,现有 API 无法捕获其他类型的警告。当您的网站使用已废弃的 API 或遇到浏览器干预时,DevTools 会首先告知您:

有关废弃和干预的开发者工具控制台警告。
开发者工具控制台中浏览器发起的警告。

人们自然会认为 window.onerror 会捕获这些警告。不会。这是因为 window.onerror 不会针对由用户代理本身直接生成的警告触发。当代码执行导致运行时错误(JavaScript 异常和语法错误)时,该事件会触发。

ReportingObserver 会接手处理。它提供了一种程序化的方式,可让您及时了解浏览器发出的警告,例如弃用干预。您可以将其用作报告工具,不必再为用户是否在您的正式版网站上遇到意外问题而操心。

API

ReportingObserver 与其他 Observer API(例如 IntersectionObserverResizeObserver)没有太大区别。您向它提供回调,它会向您提供信息。回调收到的信息是网页导致的问题列表:

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

过滤后的报告

您可以预先过滤报告,以便仅观察特定类型的报告。目前,报告类型有两种:'deprecation''intervention'

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

缓冲报告

如果您想查看在创建观察器实例之前生成的报告,请使用 buffered: true 选项:

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

此选项非常适用于延迟加载使用 ReportingObserver 的库等情况。观察器会较晚添加,但您不会错过网页加载过程中之前发生的任何情况。

停止观察

使用 disconnect() 方法停止观察:

observer.disconnect();

示例

向分析服务提供商报告浏览器干预

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

observer.observe();

在 API 即将被移除时收到通知

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

总结

ReportingObserver 为您提供了另一种发现和监控 Web 应用中潜在问题的方式。它甚至是一款有用的工具,可用于了解代码库的运行状况(或运行状况不佳)。将报告发送到后端,了解实际问题,更新代码,大功告成!

后续工作

我希望未来 ReportingObserver 能成为捕获 JavaScript 中所有类型问题的事实上的 API。假设有一个 API 可捕获应用中发生的所有错误:

其他资源

主打图片Unsplash 用户 Sieuwert Otterloo 提供。