ReportingObserver API でコードの状態を把握する

本番環境のアプリで非推奨の API を見つける。

ReportingObserver を使用すると、サイトが非推奨の API を使用している場合や、ブラウザの介入が発生した場合に通知されます。基本機能は、Chrome 69 で最初にリリースされました。Chrome 84 以降では、ワーカーで使用できます。

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

observer.observe();

コールバックを使用して、分析のためにバックエンドまたはアナリティクス プロバイダにレポートを送信します。

なぜこれが有用なのでしょうか。この API が登場するまでは、非推奨と介入の警告は、DevTools でコンソール メッセージとしてのみ利用可能でした。特に介入は、デバイスやネットワークの状態など、さまざまな現実的な制約によってのみトリガーされます。そのため、ローカルでサイトを開発またはテストしているときに、これらのメッセージが表示されないこともあります。ReportingObserver には、この問題の解決策が用意されています。ユーザーが実際の環境で潜在的な問題に遭遇した場合、ウェブ デベロッパーはその問題について通知を受け取ることができます。

背景

ウェブアプリで発生する「事象」をモニタリングする API が非常に多いことに興味を持ち、以前にブログ投稿(ウェブアプリの監視)を書きました。たとえば、DOM に関する情報を監視できる API には、ResizeObserverIntersectionObserverMutationObserver などがあります。PerformanceObserver はパフォーマンス測定をキャプチャします。window.onerrorwindow.onunhandledrejection などのメソッドでは、問題が発生したときに通知することもできます。

ただし、既存の API ではキャプチャされない他の種類の警告もあります。サイトで非推奨の API が使用されている場合や、ブラウザによる介入が発生した場合は、DevTools が最初に通知します。

非推奨と介入に関する DevTools Console の警告。
DevTools Console のブラウザ起動型の警告。

window.onerror がこれらの警告をキャプチャすると自然に考えてしまいます。いいえ。これは、ユーザー エージェント自体によって直接生成された警告に対して window.onerror がトリガーされないためです。コードの実行によって発生した実行時エラー(JavaScript 例外と構文エラー)でトリガーされます。

ReportingObserver がその差分を補います。ブラウザから発行される警告(非推奨介入など)をプログラムで通知する方法を提供します。レポート ツールとして使用することで、ユーザーが公開サイト上で予期しない問題に遭遇していないか心配する必要がなくなります。

API

ReportingObserver は、IntersectionObserverResizeObserver などの他の Observer API と似ています。コールバックを渡すと、情報が返されます。コールバックが受け取る情報は、ページによって発生した問題のリストです。

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' の 2 種類です。

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 を使用すると、ウェブアプリの潜在的な問題を検出してモニタリングする方法がさらに増えます。また、コードベースの健全性(または健全性の欠如)を把握するための便利なツールにもなります。レポートをバックエンドに送信し、実際の問題を把握してコードを更新し、利益を得る。

今後の作業

今後、ReportingObserver が JavaScript のあらゆる問題を検出するためのデファクト スタンダード API になることを願っています。アプリで発生するすべての問題をキャッチする 1 つの API があるとします。

その他のリソース:

UnsplashSieuwert Otterloo によるヒーロー画像