サービスワーカー 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 イベント内でプロミスを指定してこのメソッドを呼び出すと、プロミスが正常に解決されるまで、 fetchpush などの関数イベントはサービスワーカーに配信されません。

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

静的ルーティングを使用して、リソースの取得方法を制御

サービスワーカーは、不要なパフォーマンスコストが発生する可能性があります。しばらくぶりにページが初めて読み込まれる場合、ブラウザはサービスワーカーが起動して実行されるのを待たなければ、どのコンテンツを読み込むべきか、また、キャッシュまたはネットワークのどちらから取得すべきかを判断できません。

特定のコンテンツがどこから取得されるべきか事前に分かっている場合は、サービスワーカーを完全にバイパスして、リソースを即座に取得することができます。InstallEvent.addRoutes() メソッドは、この使用事例やその他の実装にも使用できます。

その他の使用例

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

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

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

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

インターフェイス

Cache

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

CacheStorage

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

Client

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

Clients

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

ExtendableEvent

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

ExtendableMessageEvent

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

FetchEvent

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

InstallEvent

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

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

ServiceWorker

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

ServiceWorkerContainer

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

ServiceWorkerGlobalScope

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

ServiceWorkerRegistration

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

WindowClient

アクティブなワーカーによって制御される閲覧コンテキスト内の文書であるサービスワーカークライアントのスコープを表します。これは特別な種類の Client オブジェクトで、いくつかの追加メソッドとプロパティが利用可能です。

他のインターフェイスへの拡張

Window.caches and WorkerGlobalScope.caches

現在のkンテキストに関連付けられた CacheStorage オブジェクトです。

ServiceWorkerContainer オブジェクトを返します。このオブジェクトは、関連付けられた文書ServiceWorker オブジェクトの登録、削除、アップグレード、通信へのアクセスを提供します。

仕様書

Specification
Service Workers

関連情報