サービスワーカー API
============

サービスワーカーは、基本的にウェブアプリケーション、ブラウザー、そして（もし繋がっていれば）ネットワークの間に介在するプロキシサーバーのように振る舞います。これは、よりよいオフラインの操作性を可能にするように意図されており、ネットワークのリクエストに介在してネットワークの使用可否の状況に基づいて適切な対応を取ったり、サーバー上にある資産を更新したりします。また、プッシュ通知やバックグラウンド同期の API 群へのアクセスもできるようになります。

サービスワーカーの概念と使い方
---------------

サービスワーカーは、あるオリジンとパスに対して登録されたイベント駆動型のワーカーです。 JavaScript ファイルの形を取り、ナビゲーションやリソースへのリクエストを横取りや改変したり細かい粒度でリソースをキャッシュすることで関連付けられたウェブページやサイトを制御し、それぞれの状況（もっとも顕著な例は、ネットワークが利用できないとき）にアプリがどのように振る舞うかを完全に制御することができます。

サービスワーカーはワーカーのコンテキストで実行されます。従って、DOM へアクセスすることができず、アプリを実行する主要な JavaScript とは異なるスレッドで実行されるため、他のタスクをブロックすることはありません。完全に非同期で設計されています。そのため、同期型の XHR やウェブストレージのような API をサービスワーカーで使用することはできません。

 サービスワーカーの JavaScript モジュールは動的にインポートできず、`import()` はサービスワーカーのグローバルスコープで呼び出されると例外を発生します。
 `import` 文を使用した静的インポートは許可されています。

サービスワーカーはセキュリティ上の理由から、 HTTPS 通信でのみ動作します。最も重要なことは、HTTP 接続は中間者攻撃による悪意のあるコード注入の影響を受けやすく、こうした強力な API へのアクセスを許可されると、その攻撃はより悪いものになる可能性があるということです。Firefox ではプライベートブラウジングモードでサービスワーカー API を利用することはできません。

**メモ:** Firefox では、テストのためにサービスワーカーを HTTP (安全ではない) 上で実行することができます。これは、 **HTTP による サービスワーカー を有効化 (ツールボックスを開いたとき)** オプションを Firefox Devtools 設定メニューでチェックするだけです。

**メモ:** サービスワーカーは AppCache のような、この分野における以前の試みより勝っています。以前のものは、あなたがしようとしていることを想定していなかったり、想定が正しくなかったときに壊れたりしていたのに対して、サービスワーカーはあなたがすべてを細かく制御することができるためです。

**メモ:** サービスワーカーはプロミスを頻繁に使用して、レスポンスが来るのを待ってから、成功または失敗のアクションで応答します。プロミスのアーキテクチャはこの領域に対して理想的なものです。

### 登録

サービスワーカーは最初に `ServiceWorkerContainer.register()` メソッドを使って登録されます。成功したら、サービスワーカーがクライアントにダウンロードされ、ユーザーがアクセスした URL のオリジン内全体、または指定したそのサブセット内に対してインストールと有効化（下記参照）が試みられます。

### ダウンロードとインストールと有効化

この段階で、サービスワーカーは以下のライフサイクルで実行されます。

1. ダウンロード
2. インストール
3. 有効化

ユーザーが最初にサービスワーカーが制御するサイトやページにアクセスすると、サービスワーカーが直ちにダウンロードされます。

その後、次の場面で更新されます。

* スコープ内のページへの移動が発生したとき
* サービスワーカーでイベントが発生し、かつ過去 24 時間以内にダウンロードが行われていない場合

ダウンロードしたファイルが新しいと分かった場合、既存のサービスワーカーとバイト単位に比較して異なっていた場合や、そのページやサイトで最初のサービスワーカーが見つかった場合は、インストールが試みられます。

サービスワーカーが初めて有効化されるときであれば、インストールが試みられ、インストールに成功した後で、有効化されます。

利用できる既存のサービスワーカーがあった場合は、新しいバージョンがバックグラウンドでインストールされますが、まだ有効化 (activate) されません。この時点のものを*待機中 (waiting) のワーカー*と呼びます。まだ使用している古いサービスワーカーが読み込んでいるページがなくなった時のみ、有効化されます。ページが読み込まれなくなったらすぐに、新しいサービスワーカーが有効化されます（*アクティブワーカー*になります）。 `ServiceWorkerGlobalScope.skipWaiting()` を使用するとすぐに有効化することができ、 `Clients.claim()` を使用してアクティブワーカーが既存のページの管理を始めることができます。

`install` を受け取ることもできます。イベントが発行されたときの標準的なアクションは、使用するためにサービスワーカーを準備すること、例えば組込みストレージ API を使用してキャッシュを構築したり、アプリがオフラインの時に使用したい資産をその中に配置したりすることです。

`activate` イベントもあります。このイベントが発行された時点は、古いキャッシュや、前のバージョンのサービスワーカーに関するその他のものを整理するのによいタイミングです。

サービスワーカーは `FetchEvent` イベントを使用してリクエストに応答することができます。`FetchEvent.respondWith()` メソッドを使用して、これらのリクエストに対するレスポンスを何でも思うように変更できます。

**メモ:** `install`/`activate` イベントは完了するまでに時間がかかる可能性があるため、サービスワーカーの仕様書では `waitUntil()` メソッドを提供しています。 `install` または `activate` イベント内でプロミスを指定してこのメソッドを呼び出すと、プロミスが正常に解決されるまで、 `fetch` や `push` などの関数イベントはサービスワーカーに配信されません。

最初の基本的な例をどのように構築するかについての完全なチュートリアルは、サービスワーカーの使用を読んでください。

その他の使用例
-------

サービスワーカーは次のような用途も想定しています。

* バックグラウンドのデータ同期
* 他のオリジンからのリソースのリクエストに対する応答
* 位置情報やジャイロスコープのような計算コストの高いデータの更新を集中的に受信して、複数のページがデータの一部を利用できるようにすること
* CoffeeScript, less, CJS/AMD モジュールなどの開発用途で、クライアント側のコンパイルや依存性管理
* バックグラウンドサービスのフック
* 特定の URL パターンに基づくテンプレートカスタマイズ
* パフォーマンスの改善、例えばユーザーが近く必要とするであろう、写真アルバムの次の数枚の写真などの先読み

近い将来、サービスワーカーはネイティブアプリで実現できることに近い、その他いくつもの便利なことを、ウェブプラットフォーム上でも実現する事ができるようになるでしょう。興味深いことに、次のような他の仕様書でも、サービスワーカーのコンテキストを利用できるようになってきています。

* バックグラウンド同期: ユーザーがサイトにいないときにもサービスワーカーを起動し、キャッシュを更新したりすることができます。
* プッシュメッセージへの応答: 新しいコンテンツが利用可能になった旨を伝えるためにユーザーにメッセージを送るためにサービスワーカーを起動します。
* 特定の日付・時刻に対する反応
* 特定の地理的範囲へ入った事を検知する
インターフェイス
--------

`Cache`

`ServiceWorker` のライフライクルの一部としてキャッシュされる、`Request` / `Response` オブジェクトのペアのためのストレージです。

`CacheStorage`

`Cache` オブジェクトのストレージです。これは `ServiceWorker` がアクセスできるすべての名前付きキャッシュのへの目録を提供し、文字列の名前から対応する `Cache` へのマップを保持します。

`Client`

サービスワーカークライアントのスコープを表します。サービスワーカークライアントは、ブラウザーコンテキスト内の文書または `SharedWorker` であり、アクティブワーカーによって制御されています。

`Clients`

`Client` オブジェクトのリストのためのコンテナーであり、現在のオリジンにある有効化されたサービスワーカークライアントにアクセスする主な方法です。

`ExtendableEvent`

`ServiceWorkerGlobalScope` で配信される `install` イベントや `activate` イベントのライフタイムを延ばします。これは、データベーススキーマの更新や使われなくなったキャッシュエントリーの削除などが終わるまで機能的イベント (Functional events) が `ServiceWorker` に配信されないことを保証します。

`ExtendableMessageEvent`

サービスワーカーで発生する `message` イベントのイベントオブジェクト（別のコンテキストから `ServiceWorkerGlobalScope` でチャンネルメッセージを受信した時）の有効期限を延長します。

`FetchEvent`

ハンドラー `onfetch` に渡される引数、 `FetchEvent` は `ServiceWorkerGlobalScope` で配信される読み取りアクションを表現しています。これは、リクエストと結果のレスポンスに関する情報を含み、`FetchEvent.respondWith()` メソッドを提供して、制御されたページに任意のレスポンスを返すことができます。

`InstallEvent` 
非推奨

Non-standard

`oninstall` ハンドラーに渡される引数で、 `InstallEvent` インターフェースは `ServiceWorker` の `ServiceWorkerGlobalScope` に配信されるインストールアクションを表現します。 `ExtendableEvent` の子として、`FetchEvent` のような機能イベントがインストール中に配信されないことを保証しています。

`NavigationPreloadManager`

サービスワーカーによるリソースの先読みを管理するためのメソッドを提供します。

`Navigator.serviceWorker`

`ServiceWorker` オブジェクトを返します。これにより、関連ドキュメントに対する登録、削除、アップグレード、通信へのアクセスを提供します。

`NotificationEvent`

`onnotificationclick` ハンドラーに渡される引数で、`NotificationEvent` インターフェースは `ServiceWorker` で通知クリックイベントを表現します。

`ServiceWorker`

サービスワーカーを表します。複数の閲覧コンテキスト（例：ページ、ワーカーなど）を同じ `ServiceWorker` オブジェクトに関連付けることができます。

`ServiceWorkerContainer`

サービスワーカーの登録、登録解除、更新、サービスワーカーとその登録の状態へのアクセスなどの機能を含む、ネットワークエコシステムの全体ユニットとしてのサービスワーカーを表すオブジェクトを提供します。

`ServiceWorkerGlobalScope`

サービスワーカーのグローバル実行コンテキストを表します。

`MessageEvent`

`ServiceWorkerGlobalScope` に送られるメッセージを表します。

`ServiceWorkerRegistration`

サービスワーカーの登録を表します。

`SyncEvent` 
Experimental

SyncEvent インターフェイスはサービスワーカーの `ServiceWorkerGlobalScope` で配信された同期アクションを表します。

`SyncManager` 
Experimental

同期登録を登録、およびリストするためのインターフェイスを提供します。

`WindowClient`

アクティブなワーカーによって制御されるブラウザーコンテキスト内の文書であるサービスワーカークライアントのスコープを表します。

仕様書
---

| Specification |
| --- |
| Service Workers  |

関連情報
----

* ServiceWorker Cookbook (英語)
* サービスワーカーの使用
* Service workers basic code example (英語)
* Is ServiceWorker ready? (英語)
* `Promise`