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

コールバックを使用すると、バックエンドまたはアナリティクス プロバイダにレポートを送信して、詳細な分析を行うことができます。

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

はじめに

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

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

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

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

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

API

この API は、IntersectionObserverResizeObserver などの他の「オブザーバー」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();

フィルタ適用レポート

レポートを事前にフィルタして、特定のレポート タイプのみをモニタリングできます。

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

今後の作業

今後、ReportingObserver が JS のあらゆる種類の問題を検出するための事実上の API になることを願っています。アプリで発生するすべての問題をキャッチする 1 つの API があるとします。

ReportingObserver をワークフローに統合するツールも期待しています。Lighthouse は、[非推奨の API の使用を回避する] 監査を実行するときに、ブラウザの非推奨をすでに報告するツールの例です。

非推奨の API を使用している Lighthouse 監査で ReportingObserver が使用される可能性があります。
非推奨の API の使用に関する Lighthouse 監査で ReportingObserver を使用できる。

現在、Lighthouse は DevTools プロトコルを使用してコンソール メッセージをスクレイピングし、これらの問題をデベロッパーに報告しています。代わりに、ReportingObserver に切り替えて、よく構造化された非推奨レポートと、anticipatedRemoval 日付などの追加のメタデータを利用することをおすすめします。

その他のリソース: