バックグラウンドで PWA を同期および更新する
サービス ワーカーを使用すると、プログレッシブ Web アプリ (PWA) は、ユーザーがアプリを使用していない場合でもバックグラウンドで作業を行い、より優れたオフライン エクスペリエンスを提供できます。
次のユース ケースを検討してください。
- ユーザーがメッセージを作成し、オフラインでもいつでも送信できる電子メール アプリ。
- ユーザーがアプリを開くときに後で読むための、毎日新しい記事をフェッチするニュース アプリ。
- ユーザーがオフラインで聴くための曲をダウンロードできる音楽アプリ。
これらの 3 つのユース ケースはすべて、次の API を使用して PWA で可能です。
- バックグラウンド同期 API
- 定期的なバックグラウンド同期 API
- バックグラウンド フェッチ API
これらの API の名前は似ていますが、本質的には異なります。
バックグラウンド同期 API を使用してデータをサーバーと同期する
バックグラウンド同期 API を使用して、ユーザーがオフラインの場合でもアプリを引き続き使用し、アクションを実行できるようにします。
たとえば、電子メール アプリを使用すると、ユーザーはいつでもメッセージを作成して送信できます。 アプリ フロントエンドはメッセージをすぐに送信しようとすることができ、デバイスがオフラインの場合、サービス ワーカーは失敗した要求をキャッチし、バックグラウンド同期 API を使用して、接続されるまでタスクを延期できます。
バックグラウンド同期 API を使用する別の例として、ユーザーのバックグラウンドでコンテンツを読み込むことがあります。
注:
バックグラウンド同期 API は、少量のデータに使用する必要があります。 バックグラウンド同期 API では、データ転送の間、サービス ワーカーが存続している必要があります。 バックグラウンド同期 API は、バッテリの寿命を維持するために、デバイスがサービス ワーカーを終了することを決定できるため、大きなファイルをフェッチするために使用しないでください。 代わりに、 バックグラウンド フェッチ API を使用します。
サポートを確認する
バックグラウンド同期 API は Microsoft Edge で使用できますが、アプリが実行されている他のブラウザーやデバイスで Background Sync API がサポートされていることを確認する必要があります。 バックグラウンド同期 API がサポートされていることを確認するには、 ServiceWorkerRegistration
オブジェクトに sync
プロパティがあるかどうかをテストします。
navigator.serviceWorker.ready.then(registration => {
if (registration.sync) {
// Background Sync is supported.
} else {
// Background Sync isn't supported.
}
});
ServiceWorkerRegistration
インターフェイスの詳細については、「MDN での ServiceWorkerRegistration」を参照してください。
同期を要求する
まず、同期を要求します。これは、アプリ フロントエンドまたはサービス ワーカーによって実行できます。
- フロントエンドからの同期の要求は、後で同期を担当するユーザーを残したい場合に適しています。
- これをユーザーに対して透過的にする場合は、サービス ワーカーからの同期を要求することをお勧めします。 この場合、サービス ワーカーは失敗したフェッチ要求を検出し、すぐに同期を要求できます。
同期を要求するには、 ServiceWorkerRegistration
とタグ名が必要です。 アプリ フロントエンド コードから、次の操作を行います。
async function requestBackgroundSync() {
const registration = await navigator.serviceWorker.ready;
await registration.sync.register('my-tag-name');
}
または、サービス ワーカーから、代わりに次の操作を行います。
async function requestBackgroundSync() {
await self.registration.sync.register('my-tag-name');
}
上記の my-tag-name
文字列は、複数の要求を実行できるように、この同期要求を識別する一意のタグにする必要があります。
同期イベントに反応する
接続を使用してサービス ワーカーが実行されるとすぐに、 sync
イベントがサービス ワーカーに送信されます。このイベントを使用して、必要なデータを同期できます。
sync
イベントは、次のコードでリッスンできます。
self.addEventListener('sync', event => {
if (event.tag === 'my-tag-name') {
event.waitUntil(doTheWork());
}
});
上記のコード例では、 sync
イベント リスナーがサービス ワーカーに追加されています。 リスナーが呼び出されると、コードはタグがフロントエンドに登録されたタグであるかどうかを確認し、 doTheWork
を呼び出します。 この関数は Promise を返す必要があります。
通常、 doTheWork
関数は、ユーザーがオフラインのときに送信できなかった情報をサーバーに送信します。 この情報をフロントエンドから IndexedDB ストレージに 格納すると、 doTheWork
実行時に後でサービス ワーカーから取得できるようになります。
Sync
イベント、ServiceWorkerRegistration
、SyncManager
インターフェイスの詳細については、バックグラウンド同期のドラフト仕様とバックグラウンド同期 API のドキュメントを参照してください。
デモ アプリ
マイ ムービー リスト PWA は、バックグラウンド同期 API を使用して、ユーザーがオフラインの場合に後でムービー情報をフェッチするデモ アプリです。
バックグラウンド同期をテストするには:
アプリをインストールします。
検索入力フィールドを使用して映画を検索します。
オフラインにする。 これを行うには、DevTools (F12) を開き、[ Application>Service Workers>Offline ] チェック ボックスをオンにします。
いずれかの映画の結果で、[詳細情報] を選択 します。
オフラインであること、およびムービーの詳細が後で自動的に取得されることを通知するメッセージがアプリに表示されます。
オンラインにする。 これを行うには、DevTools で [ Application>Service Workers>Offline ] チェック ボックスをオフにします。
アプリを再読み込みします。 ムービーの詳細が表示されます。
サンプル コードを確認するには、 movies-db-pwa リポジトリを確認してください。
DevTools を使用したバックグラウンド同期のデバッグ
バックグラウンド同期コードをテストするには、オフラインにしてからオンラインにしてから、Microsoft Edge が sync
イベントをトリガーするのを待つ必要はありません。 代わりに、DevTools を使用すると、バックグラウンド同期イベントをシミュレートできます。
sync
イベントをシミュレートするには:
- DevTools (F12) を開きます。
- [ Application>Service Workers] を選択します。
- 同期を登録するときに使用したタグ名を [ 同期 ] 入力フィールドに入力します。
- [ 同期 ] ボタンを選択します。
次のように、アプリによって生成されたバックグラウンド同期アクティビティを DevTools でログに記録することもできます。
- DevTools (F12) を開きます。
- [ アプリケーション>バックグラウンド同期] を選択します。
- [ イベントの記録を開始する] を選択します。
同期の登録とディスパッチは、イベント ログ テーブルに表示されます。
定期的なバックグラウンド同期 API を使用して、新しいコンテンツを定期的に取得する
定期的なバックグラウンド同期 API を使用すると、PWA はバックグラウンドで定期的に新しいコンテンツを取得できるため、ユーザーは後でアプリを再度開いたときにすぐにアクセスできます。
ユーザーがアプリを使用している間、定期的なバックグラウンド同期 API を使用して、PWA は新しいコンテンツ (新しい記事など) をダウンロードする必要はありません。 コンテンツをダウンロードするとエクスペリエンスが遅くなる可能性があるため、代わりに、より便利なタイミングでコンテンツを取得します。
注:
定期的な同期は、デバイスが既知のネットワーク (つまり、デバイスが以前に接続されているネットワーク) 上にある場合にのみ発生します。 Microsoft Edge では、ユーザーがアプリを使用する頻度に合わせて同期の頻度を制限します。
サポートを確認する
アプリが実行されているブラウザーとデバイスでこの API がサポートされているかどうかを確認するには、 ServiceWorkerRegistration
オブジェクトに periodicSync
プロパティがあるかどうかをテストします。
navigator.serviceWorker.ready.then(registration => {
if (registration.periodicSync) {
// Periodic Background Sync is supported.
} else {
// Periodic Background Sync isn't supported.
}
});
ユーザーにアクセス許可を求める
定期的なバックグラウンド同期には、ユーザーのアクセス許可が必要です。 このアクセス許可の要求は、特定のアプリケーションに対して 1 回だけ実行されます。
定期的なバックグラウンド同期を実行するアクセス許可をユーザーに求める場合は、次のように Permissions API を使用します。
const status = await navigator.permissions.query({name: 'periodic-background-sync'});
if (status.state === 'granted') {
// Periodic background sync can be used.
} else {
// Periodic background sync cannot be used.
}
Permissions API の詳細については、「MDN での アクセス許可 API 」を参照してください。
定期的な同期を登録する
定期的な同期を登録するには、最小間隔と一意のタグ名を定義する必要があります。 一意のタグ名を使用すると、複数の定期的なバックグラウンド同期を登録できます。
async function registerPeriodicSync() {
await registration.periodicSync.register('get-daily-news', {
minInterval: 24 * 60 * 60 * 1000
});
}
上記のコードで使用される minInterval
は、ミリ秒単位の 1 日に対応します。 これは最小間隔のみで、Microsoft Edge では、ネットワーク接続やユーザーがアプリに定期的に参加するかどうかなど、定期的な同期イベントを使用してサービス ワーカーにアラートを送信する前に、他の要因を考慮します。
定期的な同期イベントに対応する
Microsoft Edge が定期的な同期を実行するのに適したタイミングだと判断すると、Microsoft Edge はサービス ワーカーに periodicsync
イベントを送信します。 この periodicsync
イベントは、同期の登録時に指定されたのと同じタグ名を使用して処理できます。
self.addEventListener('periodicsync', event => {
if (event.tag === 'get-daily-news') {
event.waitUntil(getDailyNewsInCache());
}
});
getDailyNewsInCache
関数は、サービス ワーカーがサーバーから新しいコンテンツをフェッチしてキャッシュに格納できる場所です。 この関数は、同期が成功したか失敗したかを通知する Promise を返す必要があります。
PeriodicSync
イベント、ServiceWorkerRegistration
、PeriodicSyncManager
インターフェイスの詳細については、次を参照してください。
- Web の定期的なバックグラウンド同期 - ドラフト仕様。
- Web の定期的なバックグラウンド同期 API。
デモ アプリ
DevTools のヒント は、定期的なバックグラウンド同期 API を使用する PWA です。 [DevTools ヒント] PWA は、新しい開発者ツールのヒントを毎日フェッチし、キャッシュに格納して、ユーザーがオンラインかどうかにかかわらず、次回アプリを開く際にアクセスできるようにします。
GitHub のソース コードに移動します。 特に、アプリは registerPeriodicSync 関数に定期的な同期を登録します。
サービス ワーカー コードは、アプリが periodicsync
イベントをリッスンする場所です。
DevTools を使用して定期的なバックグラウンド同期をデバッグする
DevTools を使用すると、最小間隔を待機するのではなく、 periodicsync
イベントをシミュレートできます。
イベントをシミュレートするには:
- DevTools (F12) を開きます。
- [ Application>Service Workers] を選択します。
- [ 定期 同期] 入力フィールドに、定期同期を登録するときに使用したタグ名を入力します。
- [ 定期的な同期 ] ボタンを選択します。
DevTools でアプリによって生成された定期的なバックグラウンド同期アクティビティをログに記録することもできます。
- DevTools (F12) を開きます。
- [ Application>Periodic Background Sync] を選択します。
- [ イベントの記録を開始する] を選択します。
定期的な同期の登録とディスパッチがイベント ログ テーブルに表示されます。
バックグラウンド フェッチ API を使用して、アプリまたはサービス ワーカーが実行されていないときに大きなファイルをフェッチする
バックグラウンド フェッチ API を使用すると、PWA は大量のデータのダウンロードをブラウザー エンジンに完全に委任できます。 これにより、ダウンロードの進行中にアプリとサービス ワーカーをまったく実行する必要はありません。
この API は、ユーザーがオフラインのユース ケース用に大きなファイル (音楽、映画、ポッドキャストなど) をダウンロードできるようにするアプリに役立ちます。 ダウンロードはブラウザー エンジンに委任されるため、不安定な接続を処理する方法や接続の完全な損失を処理する方法を認識しているため、必要に応じてダウンロードを一時停止して再開できます。
サポートを確認する
この API がサポートされているかどうかを確認するには、 BackgroundFetchManager
コンストラクターがグローバル オブジェクトに存在するかどうかをテストします。
if (self.BackgroundFetchManager) {
// Background Fetch is supported.
} else {
// Background Fetch isn't supported.
}
バックグラウンド フェッチを開始する
バックグラウンド フェッチを開始するには:
navigator.serviceWorker.ready.then(async registration => {
const fetch = await registration.backgroundFetch.fetch('my-download-id',
fileUrls, options);
});
上記の my-download-id
は、このバックグラウンド フェッチの一意の文字列識別子である必要があります。
fileUrls
はダウンロードするファイルの一覧です。これは文字列 URL の配列になります。
options
は、ブラウザーでのダウンロード アクティビティの外観をカスタマイズするために使用できるオブジェクトです。
fetch
関数の詳細については、「BackgroundFetchManager.fetch() 」および「Background Fetch の概要」を参照してください。
App Badging API と Notifications API を使用してユーザーを再エンゲージメントする
App Badging API と Notifications API を使用して、ワークフローを中断することなく、バックグラウンド タスク、ダウンロード、または新しいコンテンツが完了したことをユーザーに知らせます。 バッジと通知を使用すると、アプリとのユーザーの再エンゲージメントが向上する可能性があります。
Microsoft Edge では、タスク バーのアプリ アイコンにバッジが表示され、通知はシステム通知センターと統合されます。
これらの API の使用方法については、「 バッジ、通知、プッシュ メッセージを使用してユーザーを再エンゲージメントする」を参照してください。