この 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
ファイルにコードが追加されたので、サンプル プロジェクトの Live バージョンにアクセスして、Service Worker の動作を確認します。
- サイトをプレビューするには、[アプリを表示] を押してから、全画面表示 を押します。
- Ctrl+Shift+J キー(Mac の場合は Command+Option+J キー)を押して DevTools を開きます。
- [コンソール] タブをクリックします。
Service Worker がインストールされ、アクティブになったことを示す、次のようなログメッセージが表示されます。
次に、[アプリケーション] タブに移動し、[Service Worker] パネルを選択します。 次のような画面が表示されます。
これは、ウェブアプリ solar-donkey.glitch.me
に対して、ソース URL が service-worker.js
の Service Worker があり、現在アクティブで実行中であることを示しています。また、現在 Service Worker によって制御されているクライアント(開いているタブ)が 1 つあることも示しています。
このパネルのリンク(Unregister
や stop
など)を使用すると、デバッグ目的で現在登録されている Service Worker を変更できます。
Service Worker の更新フローをトリガーする
Service Worker を使用して開発する際に理解すべき重要なコンセプトの 1 つは、更新フローです。
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 の [Applications] タブを開いたままページを再読み込みします。次のような結果が表示されます。
これは、この時点で 2 つのバージョンの Service Worker がインストールされていることを示しています。すでに有効になっている以前のバージョンが実行中であり、現在のページを制御しています。Service Worker の最新版は、右下に表示されています。waiting
状態であり、古い Service Worker によって制御されているすべての開いているタブが閉じるまで待機したままになります。
このデフォルトの動作により、ウェブアプリの古いバージョンと互換性のないリソースを返す fetch
ハンドラなど、新しい Service Worker が古い動作と根本的に異なる場合でも、ユーザーがウェブアプリの以前のインスタンスをすべてシャットダウンするまで有効になりません。
まとめ
これで、Service Worker を登録し、Chrome の DevTools を使用して Service Worker の動作を観察する方法を学びました。
今度は、キャッシュ戦略の実装を開始するのに適した状態です。ウェブアプリを高い確実性と確実性ですばやく読み込むために役立つすべての機能を実装できます。