同期 XMLHttpRequest() でのページ終了の改善

遅延したナビゲーションを減らす

Joe Medley
Joe Medley

ページやアプリをユーザーが閉じた時点で、送信されていないアナリティクス データやその他のデータが残っていることはよくあります。データの損失を防ぐため、一部のサイトでは XMLHttpRequest() への同期呼び出しを使用して、データがサーバーに渡されるまでページまたはアプリを開いたままにします。データの保存にはより良い方法があるだけでなく、この手法ではページの閉じが最大数秒遅れるため、ユーザー エクスペリエンスが低下します。

この慣行は変更する必要があります。ブラウザはそれに応えています。XMLHttpRequest() 仕様はすでに非推奨と削除の予定になっています。まず Chrome 80 では、複数のイベント ハンドラ(具体的には beforeunloadunloadpagehidevisibilitychange)が消去時に呼び出されたときに、その内部で同期呼び出しを禁止することで、同期呼び出しを禁止しています。WebKit でも最近、同じ動作変更を実装する commit がリリースされました。

この記事では、時間が必要なサイトの更新方法と、XMLHttpRequest() に代わる選択肢について簡単に説明します。

一時的なオプトアウト

Chrome は XMLHttpRequest() を完全に廃止するわけではありません。そのため、一時的にオプトアウトするオプションがいくつか用意されています。インターネット上のサイトについては、オリジン トライアルを利用できます。ここでは、オリジン固有のトークンをページヘッダーに追加して、XMLHttpRequest() の同期呼び出しを有効にします。このオプションは、Chrome 89 のリリース直前(2021 年 3 月)に終了します。Chrome Enterprise をご利用のお客様は、AllowSyncXHRInPageDismissal ポリシー フラグも使用できます。このフラグも同時にサポートが終了します。

代替

データをサーバーに返す方法にかかわらず、ページの読み込みが完了するまで待ってからすべてのデータを一度に送信することは避けてください。アンロードは、ユーザー エクスペリエンスを損なうだけでなく、最新のブラウザでは信頼性が低く、問題が発生した場合にデータが失われるリスクがあります。具体的には、モバイル ブラウザではアンロード イベントが発生しないことが多いです。これは、モバイル オペレーティング システムでは、unload イベントが発生しなくてもタブやブラウザを閉じる方法が多数あるためです。XMLHttpRequest() では、小さなペイロードを使用する方法がありました。現在は必須です。どちらの代替方法も、仕様で要求されているように、コンテキストあたりのアップロード上限が 64 KB です。

キープアライブを取得する

Fetch API は、サーバーとのやり取りを処理するための堅牢な手段と、さまざまなプラットフォーム API で使用できる一貫したインターフェースを提供します。オプションには keepalive があり、リクエストを行ったページが開いたままかどうかにかかわらず、リクエストが続行されます。

window.addEventListener('unload', {
  fetch('/siteAnalytics', {
    method: 'POST',
    body: getStatistics(),
    keepalive: true
  });
}

fetch() メソッドには、サーバーに送信される内容をより細かく制御できるという利点があります。この例では、fetch()Response オブジェクトで解決される Promise も返すことは示していません。ページのアンロードを妨げないようにするため、何もしないことにしました。

SendBeacon()

SendBeacon() は、内部で Fetch API を使用しています。そのため、ペイロードの上限が 64 KB に制限され、ページの読み込みが完了した後もリクエストが続行されます。主な利点はシンプルさです。1 行のコードでデータを送信できます。

window.addEventListener('unload', {
  navigator.sendBeacon('/siteAnalytics', getStatistics());
}

まとめ

ブラウザ間で fetch() の可用性が向上するにつれて、XMLHttpRequest() はいずれウェブ プラットフォームから削除される予定です。ブラウザベンダーは削除する必要があることに同意していますが、時間がかかります。最も悪いユースケースの一つを非推奨とすることは、すべてのユーザーのユーザー エクスペリエンスを向上させる最初のステップです。

写真提供: Matthew HamiltonUnsplash