Service Worker

ユーザーは、ネットワーク接続が遅い、不安定な場合、あるいはオフラインでも、確実に起動することを期待しています。メディア トラック、チケット、旅行プランなど、最後に操作したコンテンツが利用可能かつ使用可能であることを期待します。リクエストを実行できない場合、ユーザーは通知なく失敗したりクラッシュしたりするのではなく、アプリが通知することを期待します。そして、これらすべてを迅速に実現したいとも考えています。ミリ秒の差が数百万ドルに示したように、読み込み時間が 0.1 秒短縮されたとしても、コンバージョンが最大 10% 向上する可能性があります。Service Worker は、プログレッシブ ウェブアプリ(PWA)でユーザーの期待に応えるツールです。

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

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

Service Worker を登録する

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

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

if ('serviceWorker' in navigator) {
   navigator.serviceWorker.register("/serviceworker.js");
}
Service Worker を登録して、ブラウザのデベロッパー ツールでどうなるかを確認してください。

Service Worker が登録されているかどうかを確認する

Service Worker が登録されているかどうかを確認するには、任意のブラウザでデベロッパー ツールを使用します。

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

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

Safari の場合:

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

範囲

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

スコープごとに使用できる Service Worker は 1 つのみです。Service Worker がアクティブかつ実行中の場合、メモリ内のクライアント(PWA ウィンドウまたはブラウザタブ)の数に関係なく、通常は 1 つのインスタンスのみを使用できます。

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

ライフサイクル

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

Service Worker のライフサイクルは、Service Worker の登録から始まります。その後、ブラウザは Service Worker ファイルをダウンロードして解析しようとします。解析が成功すると、Service Worker の install イベントが発生します。install イベントは 1 回だけ発生します。

Service Worker のインストールは、ユーザーが PWA をインストールしていない場合でも、ユーザー権限なしで自動的に行われます。Service Worker API は、PWA のインストールをサポートしていないプラットフォーム(デスクトップ デバイスの Safari や Firefox など)でも使用できます。

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

Service Worker のグローバル スコープ内のイベントをリッスンするには、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 は、クライアントを制御する Service Worker と、サーバーの Service Worker ファイルの新しいバージョンがバイト単位で異なることをブラウザが検出すると、更新されます。

インストールが正常に完了すると、古い Service Worker がクライアントを制御しなくなるまで、新しい Service Worker は有効化を待機します。この状態は「待機中」と呼ばれます。ブラウザでは、この状態に基づいて、一度に 1 つのバージョンの Service Worker のみが実行されます。

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

Service Worker の存続期間

インストール済みおよび登録された Service Worker は、そのスコープ内のすべてのネットワーク リクエストを管理できます。PWA は独自のスレッドで実行され、有効化と終了はブラウザで制御されるため、PWA を開く前または閉じた後でも動作します。Service Worker は独自のスレッドで実行されますが、メモリ内の状態は Service Worker の実行間で保持されない可能性があるため、実行ごとに再利用したいものが IndexedDB または他の永続ストレージで利用可能であることを確認してください。

Service Worker がまだ実行されていない場合は、スコープでネットワーク リクエストが送信されるたびに、または定期的なバックグラウンド同期や push メッセージなどのトリガーとなるイベントを受信するたびに開始されます。

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

機能

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

Service Worker の機能は、プロキシや HTTP リクエストの処理だけを目的としていません。バックグラウンド コードの実行、ウェブプッシュ通知、支払い処理など、他の目的にも他の機能を使用できます。これらの追加については、機能で説明します。

リソース