Service Worker

ユーザーは、ネットワーク接続が低速または不安定な場合や、オフラインの場合でも、アプリが確実に起動することを期待しています。ユーザーは、最近操作したコンテンツ(メディア トラック、チケット、旅程など)が利用可能で、使用できることを期待しています。リクエストができない場合は、アプリがサイレントで失敗したりクラッシュしたりするのではなく、ユーザーに通知することを期待しています。そして、これらすべてが迅速に実行されることを望んでいます。ミリ秒がもたらす大きな効果で説明しているように、読み込み時間を 0.1 秒短縮するだけでも、コンバージョン率を最大 10% 向上させることができます。サービス ワーカーは、プログレッシブ ウェブアプリ(PWA)がユーザーの期待に応えるためのツールです。

ミドルウェア プロキシとしてのサービス ワーカー。PWA とサーバー(独自のサーバーとクロスドメイン サーバーの両方を含む)の間でデバイス側で実行されます。
サービス ワーカーは、PWA と PWA がやり取りするサーバーの間のミドルウェアとして機能します。

アプリがサービス ワーカーのスコープでカバーされているリソースをリクエストすると、ユーザーがオフラインの場合でも、サービス ワーカーがリクエストをインターセプトしてネットワーク プロキシとして機能します。その後、Cache Storage API を使用してキャッシュからリソースを提供するか、アクティブなサービス ワーカーがないかのようにネットワークから提供するか、ローカル アルゴリズムから作成するかを決定できます。これにより、アプリがオフラインの場合でも、プラットフォーム アプリのような高品質のエクスペリエンスを提供できます。

Service Worker を登録する

サービス ワーカーがページを制御する前に、PWA に登録する必要があります。つまり、ユーザーが PWA を初めて開いたときは、Service Worker がまだページを制御していないため、すべてのネットワーク リクエストがサーバーに直接送信されます。

ブラウザが Service Worker API をサポートしているかどうかを確認したら、PWA は Service Worker を登録できます。読み込みが完了すると、サービス ワーカーは PWA とネットワークの間に自身をセットアップし、リクエストをインターセプトして対応するレスポンスを返します。

if ('serviceWorker' in navigator) {
   navigator.serviceWorker.register("/serviceworker.js");
}

サービス ワーカーが登録されているかどうかを確認する

サービス ワーカーが登録されているかどうかを確認するには、お気に入りのブラウザのデベロッパー ツールを使用します。

Firefox と Chromium ベースのブラウザ(Microsoft Edge、Google Chrome、Samsung Internet)の場合:

  1. デベロッパー ツールを開き、[アプリケーション] タブをクリックします。
  2. 左側のペインで [Service Workers] を選択します。
  3. サービス ワーカーのスクリプト URL が [Activated](有効)のステータスで表示されていることを確認します。(詳細については、ライフサイクルをご覧ください)。Firefox では、ステータスは「実行中」または「停止」になります。

Safari の場合:

  1. [開発] > [サービス ワーカー] をクリックします。
  2. このメニューで、現在のオリジンを含むエントリを確認します。このエントリをクリックすると、サービス ワーカーのコンテキストのインスペクタが開きます。
Chrome、Firefox、Safari のサービス ワーカー デベロッパー ツール。
Chrome、Firefox、Safari のサービス ワーカー デベロッパー ツール。

範囲

サービス ワーカーが配置されているフォルダによって、そのスコープが決まります。example.com/my-pwa/sw.js に存在するサービス ワーカーは、my-pwa パス以下(example.com/my-pwa/demos/ など)のナビゲーションを制御できます。サービス ワーカーは、スコープ内のアイテム(ページ、ワーカー。総称して「クライアント」)のみを制御できます。このスコープは、ブラウザタブと PWA ウィンドウに適用されます。

スコープごとに許可されるサービス ワーカーは 1 つだけです。サービス ワーカーがアクティブで実行中の場合、メモリ内のクライアント(PWA ウィンドウまたはブラウザタブ)の数に関係なく、通常は 1 つのインスタンスのみが使用可能です。

Safari には、パーティションと呼ばれるより複雑なスコープ管理があり、クロスドメイン iframe でのスコープの動作に影響します。WebKit の実装について詳しくは、こちらのブログ投稿をご覧ください。

Lifecycle

サービス ワーカーには、PWA のインストールとは別に、インストール方法を規定するライフサイクルがあります。

サービス ワーカーのライフサイクルは、サービス ワーカーの登録から始まります。ブラウザは、サービス ワーカー ファイルのダウンロードと解析を試みます。解析が成功すると、サービス ワーカーの install イベントがトリガーされます。install イベントは 1 回のみ発生します。

ユーザーが PWA をインストールしていない場合でも、サービス ワーカーのインストールはユーザーの権限を必要とせず、通知なしで行われます。Service Worker API は、パソコンの Safari や Firefox など、PWA のインストールをサポートしていないプラットフォームでも利用できます。

インストール後、サービス ワーカーは、PWA などのクライアントを制御する前に有効にする必要があります。サービス ワーカーがクライアントを制御する準備ができると、activate イベントが発火します。ただし、デフォルトでは、有効化された Service Worker は、ページを再読み込みするか PWA を再度開いてそのページに移動するまで、登録したページを管理できません。

self オブジェクトを使用して、サービス ワーカーのグローバル スコープでイベントをリッスンできます。

serviceworker.js

// This code executes in its own worker or thread
self.addEventListener("install", event => {
   console.log("Service worker installed");
});
self.addEventListener("activate", event => {
   console.log("Service worker activated");
});

サービス ワーカーを更新する

サービス ワーカーは、クライアントを制御するサービス ワーカーとサーバーのサービス ワーカー ファイルの新しいバージョンがバイト単位で異なることをブラウザが検出すると更新されます。

インストールが成功すると、新しい Service Worker は、古い Service Worker がクライアントを制御しなくなるまでアクティブ化を待ちます。この状態は「待機中」と呼ばれ、ブラウザが一度に実行されるサービス ワーカーのバージョンを 1 つだけにするために使用されます。

ページを更新したり、PWA を再度開いたりしても、新しい Service Worker が制御を引き継ぐことはありません。ユーザーは、現在のサービス ワーカーを使用しているすべてのタブとウィンドウを閉じるか、そこから移動してから戻り、新しいサービス ワーカーに制御を渡す必要があります。詳しくは、サービス ワーカーのライフサイクルをご覧ください。

Service Worker の有効期間

インストールされ登録されたサービス ワーカーは、そのスコープ内のすべてのネットワーク リクエストを管理できます。独自のスレッドで実行され、ブラウザによってアクティベーションと終了が制御されるため、PWA が開く前や閉じた後でも動作します。サービス ワーカーは独自のスレッドで実行されますが、サービス ワーカーの実行間でメモリ内状態が保持されない可能性があるため、各実行で再利用するものは IndexedDB または他の永続ストレージで使用できるようにしてください。

まだ実行されていない場合、サービス ワーカーは、スコープ内でネットワーク リクエストが送信されたとき、または定期的なバックグラウンド同期やプッシュ メッセージなどのトリガー イベントを受信したときに起動します。

サービス ワーカーは、数秒間アイドル状態が続いた場合や、長時間ビジー状態が続いた場合に終了します。このタイミングはブラウザによって異なります。サービス ワーカーが終了し、起動するイベントが発生すると、再起動します。

機能

登録済みでアクティブなサービス ワーカーは、PWA のメインスレッドとはまったく異なる実行ライフサイクルを持つスレッドを使用します。ただし、デフォルトでは、サービス ワーカー ファイル自体には動作がありません。リソースのキャッシュ保存や配信は行いません。これらはコードで行う必要があります。その方法については、以降の章で説明します。

サービス ワーカーの機能は、HTTP リクエストのプロキシや処理だけではありません。バックグラウンドでのコード実行、ウェブ プッシュ通知、支払いの処理など、他の目的でこの上に他の機能が用意されています。これらの追加については、機能で説明します。

リソース