PWA: Workbox Background Sync 和訳

# Workbox Background Sync

参照元ページ: https://developers.google.com/web/tools/workbox/modules/workbox-background-sync

## Workbox Background Syncとは？

たまにウェブサーバーにデータを送る時失敗する時があります。それはインターネットに繋がっていなかったり、サーバーが落ちていることが原因かもしれません。いずれにしてもこのような場合、あなたは時間をおいて再度リクエストを送ろうとします。

[BackgroundSync API](https://wicg.github.io/BackgroundSync/spec/)という新しい技術を使えば上記の問題を最適な形で解決できます。サービスワーカーがネットワークリクエストが失敗したことを感知すると、`sync`イベントを受け取る準備をします。ネットワークコネクションが戻ったことをブラウザが認識すると`sync`イベントが渡されます。`sync`イベントはユーザがアプリケーションから離れた時にも送られます。失敗したリクエストに対する伝統的なアプローチよりも効果的です。

Workbox Background SyncはBackgroundSync APIを簡単に利用できるようにデザインされており、他のWorkboxモジュールとの組み込み工数も軽減してくれます。また、BackgroundSync APIをサポートしていないブラウザに対するフォールバックもサポートしています。

BackgroundSync APIをサポートしているブラウザは自動的にあなたに変わって[定期的にリクエストを送り](https://developers.google.com/web/updates/2015/12/background-sync#how_to_request_a_background_sync)、エクスポネンシャルバックオフ(補足: 最大再試行回数に達するまで、指数関数的に増加する待機時間で操作を再試行する手法 – 1秒、2秒、4秒、8秒、16秒...とシステムに負担をかけない)を採用しています。BackgroundSync API非サポートブラウザではWorkbox Background Syncはサービスワーカーが起動したら自動的にリクエストを送ろうとします。

## 基本的な使い方

Workbox Background Syncプラグインを使えば、失敗したリクエストをキューとして貯めてゆき、`sync`イベントが渡された時にリクエストを再試行します。

```js

const bgSyncPlugin = new workbox.backgroundSync.Plugin('myQueueName', {
  maxRetentionTime: 24 * 60 // 最大24時間の間にリクエストを再試行します
});

workbox.routing.registerRoute(
  /\/api\/.*\/*.json/,
  new workbox.strategies.NetworkOnly({
    plugins: [bgSyncPlugin]
  }),
  'POST'
);
```

## 応用編

Workbox Background SyncはQueueクラスを提供します。このインスタンスを作成し、失敗したリクエストを貯めることができます。失敗したリクエストはIndexedDBに保存され、ブラウザがオンラインになったと認識した時(`sync`イベントを受け取った時)に再度送られます。

### Queueを作成する

Workbox Background Sync Queueを作成するには、queue名(オリジンに対して一意のもの)を渡して初期化する必要があります。

```js

const queue = new workbox.backgroundSync.Queue('myQueueName');
```

queue名はグローバル[SyncManager](https://wicg.github.io/BackgroundSync/spec/#sync-manager-interface)に登録されるときのタグ名としても使われます。またIndexedDBデータベースの[Object Store](https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore)の名前にも利用されます。

注: これらの詳細はそこまで重要ではありませんが、queue名がオリジンに対して一意である理由がここにあります。


### Queueにリクエストを貯める

Queueインスタンスを生成したら、それに対して失敗したリクエストを`addRequest()`メソッドで追加することができます。例えば、次のコードは失敗したリクエストを全てキャッチし、queueに追加しています。

```js

const queue = new workbox.backgroundSync.Queue('myQueueName');

self.addEventListener('fetch', (event) => {
  // Queueに追加された時に読み込めるようにリクエストをクローンします
  const promiseChaine = fetch(event.request.clone())
    .catch((err) => {
      return queue.addRequest(event.request);
    });
});
```

queueが追加されたら、そのリクエストは自動的に再試行されます(`sync`イベントを受け取った時)。

## Workbox Background Syncを試してみる

悲しいことにBackgroundSync syncのテストは直感的でなく、多くの理由で難しいのです。

ベストアプローチは次の通りです。
1. ページを読み込み、サービスワーカーを登録します。
2. インターネットを遮断するか(オフライン)、ウェブサーバーを落としてください。**Chrome DevToolのOfflineモードは使用しないでください！** Devtoolのofflineチェックボックスはページからのリクエストのみに影響があります。サービスワーカーのリクエストは成功してしまいます。
3. Workbox Background Syncにqueueが貯まるようにネットワークリクエストをしてください。queueされたリクエストを見る場合は、```Chrome DevTools > Application > IndexedDB > workbox-background-sync > requests```で確認できます。
4. ネットワークに繋ぐか、ウェブサーバーを復活してください。
5. ```Chrome DevTools > Application > Service Workers```で`sync`イベントを発火させてください。そしてタグ名を入力します。```workbox-background-sync:<your queue name>```
![](https://developers.google.com/web/tools/workbox/images/modules/workbox-background-sync/devtools-sync.png)
6. そうするとIndexedDBに貯まっていたリクエストがうまく通って、貯まっていたリクエストが空になっていることがわかります。