Service Worker の操作

この Codelab では、ウェブ アプリケーション内から Service Worker を登録し、Chrome DevTools を使用してその動作を監視する方法について説明します。また、Service Worker を使用する際に役立つ可能性のあるデバッグ手法についても説明します。

サンプル プロジェクトに慣れる

サンプル プロジェクトのファイルのうち、この Codelab に最も関連するものは、以下のとおりです。

  • register-sw.js は最初は空ですが、Service Worker の登録に使用するコードが含まれています。これは、プロジェクトの index.html 内にある <script> タグによってすでに読み込まれています。
  • service-worker.js も同様に空です。このファイルに このプロジェクトの Service Worker が含まれます

Service Worker の登録コードを追加する

Service Worker は(現在の service-worker.js ファイルなどの空の場合でも)最初に登録されない限り使用されません。これを行うには、次の呼び出しを行います。

navigator.serviceWorker.register(
  '/service-worker.js'
)

register-sw.js ファイル内。

ただし、そのコードを追加する前に、考慮すべき点がいくつかあります。

まず、すべてのブラウザが Service Worker をサポートしているわけではありません。これは、自動更新されない古いバージョンのブラウザには特に当てはまります。そのため、navigator.serviceWorker がサポートされているかどうかを確認した後、条件付きで navigator.serviceWorker.register() を呼び出すことをおすすめします。

次に、Service Worker を登録すると、ブラウザは service-worker.js ファイル内のコードを実行します。Service Worker の install イベント ハンドラと activate イベント ハンドラ内のコードによっては、キャッシュへの入力のために URL のダウンロードを開始する場合があります。

追加のコードを実行してアセットをダウンロードすると、ブラウザが現在のウェブページを表示するために使用できる貴重なリソースを消費する可能性があります。このような干渉を回避するには、ブラウザが現在のページのレンダリングを完了するまで、Service Worker の登録を遅らせることをおすすめします。これを簡単に概算するには、window.load イベントが発生するまで待つことをおすすめします。

これら 2 つのポイントを合わせ、次の汎用 Service Worker 登録コードを register-sw.js ファイルに追加します。

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/service-worker.js');
  });
}

Service Worker のロギングコードを追加する

service-worker.js ファイルには、通常、Service Worker 実装のすべてのロジックが含まれます。Service Worker のライフサイクル イベントCache Storage API、ウェブアプリのネットワーク トラフィックに関する情報を組み合わせて、ウェブアプリのすべてのリクエストを処理できる精巧な Service Worker を作成します。

でも... では後でまた学びましょう。この段階では、さまざまな Service Worker イベントを監視し、Chrome の DevTools を使用して Service Worker の状態をデバッグする方法に重点を置いています。

そのためには、次のコードを service-worker.js に追加します。これにより、さまざまなイベントに対応してメッセージが DevTools コンソールに記録されます(その他のイベントは行われません)。

self.addEventListener('install', (event) => {
  console.log('Inside the install handler:', event);
});

self.addEventListener('activate', (event) => {
  console.log('Inside the activate handler:', event);
});

self.addEventListener(fetch, (event) => {
  console.log('Inside the fetch handler:', event);
});

DevTools の [Service Workers] パネルについて理解する

register-sw.js ファイルと service-worker.js ファイルにコードを追加したので、サンプル プロジェクトのライブ バージョンにアクセスし、Service Worker の動作を確認します。

  • サイトをプレビューするには、[View App] を押してから、[Fullscreen] 全画面表示 を押します。
  • Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
  • [コンソール] タブをクリックします。

次のようなログメッセージが表示されます。これは、Service Worker がインストールされ、有効になったことを示しています。

Service Worker がインストールされ、有効化されていることを示します。

次に、[アプリケーション] タブに移動し、[Service Worker] パネルを選択します。次のような画面が表示されます。

Service Worker パネルに Service Worker の詳細を表示します。

これは、ウェブアプリ solar-donkey.glitch.me に対して、ソース URL が service-worker.js の Service Worker があり、現在アクティブで実行中であることを示しています。また、現在 1 つのクライアント(開いているタブ)が Service Worker によって制御されていることもわかります。

このパネルのリンク(Unregisterstop など)を使用して、現在登録されている Service Worker にデバッグの目的で変更を加えることができます。

Service Worker の更新フローをトリガーする

Service Worker で開発を行う際に理解しておくべき重要なコンセプトの一つは、更新フローです。

Service Worker を登録するウェブアプリにユーザーがアクセスすると、service-worker.js の現在のコピーのコードがローカル ブラウザにインストールされます。しかし、ウェブサーバーに保存されている service-worker.js のバージョンを更新するとどうなるでしょうか。

リピーターが Service Worker のスコープ内の URL に戻ると、ブラウザは自動的に最新の service-worker.js をリクエストし、変更がないかをチェックします。Service Worker スクリプトの内容が異なる場合、新しい Service Worker はインストールと有効化を行い、最終的に制御を取得します。

プロジェクトのコードエディタに戻り、コードに任意の変更を加えることで、このアップデート フローをシミュレートできます。簡単な変更の一つとして

self.addEventListener('install', (event) => {
  console.log('Inside the install handler:', event);
});

動画ブーストあり

self.addEventListener('install', (event) => {
  console.log('Inside the UPDATED install handler:', event);
});

変更後、サンプルアプリのライブ バージョンに戻り、DevTools の [Application] タブを開いた状態でページを再読み込みします。次のように表示されます。

Service Worker の 2 つのバージョンがインストールされていることが示されています。

これは、この時点でインストールされている Service Worker に 2 つのバージョンがあることを示しています。すでに有効化されている以前のバージョンが実行中で、現在のページが制御されています。Service Worker の更新版は右下に示しています。この状態は waiting 状態であり、古い Service Worker によって制御されている開いているタブがすべて閉じられるまで待機します。

このデフォルトの動作により、新しい Service Worker の動作が古い Service Worker と根本的に異なる場合(たとえば、古いバージョンのウェブアプリと互換性のないリソースで応答する fetch ハンドラなど)、ユーザーがウェブアプリの以前のインスタンスをすべてシャットダウンするまで有効になりません。

まとめ

ここでは、Chrome の DevTools を使用して Service Worker を登録し、Service Worker の動作を確認する手順を学びました。

これで、キャッシュ戦略の実装を開始する準備が整いました。また、ウェブアプリを確実かつ高速に読み込むために役立つさまざまな機能を実装しました。