ウェブサーバーに対してリクエストを行う場合、エラーが発生する可能性があります。ユーザーの接続が切断されているか、リモート サーバーがダウンしている可能性があります。
このドキュメントでは主に Service Worker での GET
リクエストの処理に重点を置いていますが、POST
、PUT
、DELETE
などの他のメソッドも使用する場合があります。これらのメソッドは、バックエンド API と通信してウェブアプリにデータを提供する際によく使用されます。Service Worker が存在せずこれらのリクエストが失敗した場合は、オンラインに戻ったときにユーザーが手動で再試行する必要があります。これはユーザーが必ず覚えておくべきことではありません。
これがアプリケーションに当てはまる場合、かつ Service Worker が混在している場合、ユーザーがオンラインに戻ったときに失敗したリクエストの送信を再試行するのが理想的です。この問題の解決策は、BackgroundSync API です。Service Worker は、ネットワーク リクエストの失敗を検出し、ブラウザが接続の復旧を検出したときに sync
イベントを受信するよう設定できます。sync
イベントは、ユーザーがそれを登録したページから移動した場合でも配信できるため、失敗したリクエストを再試行する他の方法よりも効果的です。
ワークボックスは、workbox-background-sync
モジュールでこの API を抽象化し、BackgroundSync API を他のワークボックス モジュールと併用しやすくしています。また、BackgroundSync をまだサポートしていないブラウザ用のフォールバック戦略も実装されています。
基本的な使用方法
BackgroundSyncPlugin
は workbox-background-sync
モジュールからエクスポートされ、失敗したリクエストをキューに入れておき、その後の sync
イベントが発生したときに再試行するために使用できます。
import {BackgroundSyncPlugin} from 'workbox-background-sync';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
const bgSyncPlugin = new BackgroundSyncPlugin('myQueueName', {
maxRetentionTime: 24 * 60 // Retry for max of 24 Hours (specified in minutes)
});
registerRoute(
/\/api\/.*\/*.json/,
new NetworkOnly({
plugins: [bgSyncPlugin]
}),
// An optional third parameter specifies the request method
'POST'
);
ここでは、BackgroundSyncPlugin
が、JSON データを取得する API ルートへの POST リクエストに一致するルートに適用されます。ユーザーがオフラインの場合、BackgroundSyncPlugin
はユーザーがオンラインに戻ったときにリクエストを再試行しますが、再試行できるのは最大で 1 日間です。
高度な使用方法
workbox-background-sync
には、失敗したリクエストをインスタンス化して追加できる Queue
クラスも用意されています。BackgroundSyncPlugin
の場合と同様に、失敗したリクエストは IndexedDB に保存され、接続が復元されたとブラウザが判断したときに試行されます。
キューの作成
キューを作成するには、キュー名を表す文字列を使用して Queue
オブジェクトをインスタンス化します。
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
キュー名は、グローバル SyncManager
によって提供される register()
メソッドによって作成されるタグ名の一部として使用されます。これは、IndexedDB データベースで提供されるオブジェクト ストアに使用される名前でもあります。
キューにリクエストを追加する
Queue
インスタンスを作成したら、その pushRequest()
メソッドを使用して、失敗したリクエストを追加できます。
import {Queue} from 'workbox-background-sync';
const queue = new Queue('myQueueName');
self.addEventListener('fetch', (event) => {
// Add in your own criteria here to return early if this
// isn't a request that should use background sync.
if (event.request.method !== 'POST') {
return;
}
const bgSyncLogic = async () => {
try {
const response = await fetch(event.request.clone());
return response;
} catch (error) {
await queue.pushRequest({request: event.request});
return error;
}
};
event.respondWith(bgSyncLogic());
});
キューに追加されたリクエストは、Service Worker が sync
イベントを受け取ると自動的に再試行します。これは、ネットワークが再び利用可能になったとブラウザが判断するためです。BackgroundSync API をサポートしていないブラウザは、Service Worker が起動するたびにリクエストを再試行します。これは、失敗したリクエストを再試行する効果的な方法ではなく、一種の代替方法です。
workbox-background-sync
のテスト
バックグラウンド同期の動作のテストは難しい場合がありますが、Chrome DevTools で行うことができます。現在の最善のアプローチは次のようになります。
- Service Worker を登録するページを読み込みます。
- パソコンのネットワーク接続をオフにするか、ウェブサーバーをオフにします。Chrome DevTools のオフライン切り替えボタンは使用しないでください。[オフライン] チェックボックスはページからのリクエストにのみ影響し、Service Worker のリクエストは引き続き処理されます。
workbox-background-sync
でキューに入れるネットワーク リクエストを作成します。Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests
を調べると、キューに入れられたリクエストを確認できます。- ネットワーク接続を復元するか、ウェブサーバーをオンに戻してください。
Chrome DevTools > Application > Service Workers
に移動して、早期sync
イベントを強制実行します。workbox-background-sync:<your queue name>
のタグ名を入力します。ここで、<your queue name>
は、設定したキューの名前です。- [同期] ボタンをクリックします。
- 以前に失敗したネットワーク リクエストが再試行され、完了したことがわかります。その結果、リクエストが正常にリプレイされたため、IndexedDB ストアは空になります。
まとめ
workbox-background-sync
を使用して失敗したネットワーク リクエストを再試行すると、アプリのユーザー エクスペリエンスと信頼性を向上させることができます。たとえば、失敗した API リクエストを再送信できるため、API に送信するデータが失われないようにすることができます。また、分析など、独自のデータのギャップを埋めるために使用することもできます。実際に、workbox-google-analytics
モジュールは内部で workbox-background-sync
を使用して、Google アナリティクスへのデータ送信に失敗したリクエストを再試行します。
ユースケースが何であれ、workbox-background-sync
はこの種のタスクを簡素化し、デベロッパー エクスペリエンスを向上させ、ウェブ アプリケーションのユーザー エクスペリエンスと機能を向上させる機会を提供します。