ReportingObserver:了解代码的运行状况

要点

小镇新面孔!ReportingObserver 是一个新 API,可让您了解您的网站何时使用了已弃用的 API 或遇到浏览器干预

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

observer.observe();

该回调可用于将报告发送到后端或分析服务提供商以进行进一步分析。

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

简介

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

不过,这些现有 API 无法捕获其他类型的警告。当您的网站使用已弃用的 API 或遭到浏览器干预时,开发者工具会首先通知您:

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

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

ReportingObserver 会接手处理。它提供了一种程序化的方式,可让您及时了解浏览器发出的警告,例如废弃干预。您可以将其用作报告工具,避免担心用户在您的实际网站上遇到意外问题。

API

该 API 与其他“观察器”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();

过滤后的报告

您可以预先过滤报告,以便仅观察特定报告类型:

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

缓冲报告

如果您想查看在创建观察器之前生成的报告,buffered: true 选项非常有用:

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

它非常适合在使用 ReportingObserver 的库延迟加载等情况下使用。观察者添加的时间较晚,但您不会错过网页加载早期发生的任何事件

停止观察

有!它有一个 disconnect 方法:

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

示例

示例 - 向分析服务提供商报告浏览器干预情况:

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 能成为用于捕获 JS 中所有类型问题的事实上的 API。假设有一个 API 可以捕获您应用中所有出错的地方:

  • 浏览器干预
  • 弃用
  • 功能政策违规。请参阅 crbug.com/867471
  • JS 异常和错误(目前由 window.onerror 处理)。
  • 未处理的 JS promise 拒绝(目前由 window.onunhandledrejection 处理)

我也很期待看到将 ReportingObserver 集成到其工作流中的工具。Lighthouse 就是这样一款工具,当您运行其“避免使用已废弃的 API”审核时,它会标记浏览器废弃情况:

用于检查是否使用已废弃 API 的 Lighthouse 审核可以使用 ReportingObserver。
针对使用已废弃 API 的 Lighthouse 审核可以使用 ReportingObserver。

Lighthouse 目前使用 DevTools 协议抓取控制台消息,并将这些问题报告给开发者。不过,改用 ReportingObserver 以获取结构合理的弃用报告以及 anticipatedRemoval 日期等其他元数据可能会很有趣。

其他资源