同期 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() はいずれウェブ プラットフォームから削除される予定です。ブラウザ ベンダーは削除すべきであることに同意していますが、時間がかかります。最悪のユースケースの 1 つを非推奨にすることは、すべてのユーザーのユーザー エクスペリエンスを向上させるための最初のステップです。

写真提供: Matthew HamiltonUnsplash