1. このページの目的
Service Worker の基本的な動作を検証する。
2. このページにおける Service Worker の状態
本ページでは、ページロード時に Service Worker を読み込んでいる。
サーバー側の service-worker.js
を編集して更新したり(運営者のみ可能)、ブラウザを更新したりすると、ServiceWorker の state が変更されるのでそれを眺める。
Chrome DevTools の「Console パネル」や「Application パネル - Service Workers」も観察すること。特に後者ではいろいろ操作できるので触ってみる。
順序 | ページロード時 ServiceWorkerが入っていたプロパティ | ServiceWorkerのstateとその後の変化 (なければ空) |
説明 |
---|---|---|---|
1 | ServiceWorkerRegistration.installing |
|
|
2 | ServiceWorkerRegistration.waiting |
|
|
3 | ServiceWorkerRegistration.active |
|
|
- | ServiceWorkerContainer.controller (ServiceWorkerが更新されたら、こちらも更新される) |
|
3. コントロールパネル
※ ServiceWorker からメッセージを受け取るのは、ServiceWorkerContainer である。
※ メッセージ送信を行って何もメッセージが表示されない場合は、ServiceWorker にメッセージは送れたが、ServiceWorker からこちら側にメッセージが送れなかった可能性がある。
4. コード
メインスレッドの JavaScriptコードは、このページのソースコードに書いてある。
service-worker.js
のコードのみ以下に記載する。
self.addEventListener('message', async (event) => {
await self.clients.matchAll().then(clients => {
const clientCount = clients.length;
console.log('clientCount =', clientCount);
clients.forEach((client, idx) => {
client.postMessage({
message: `on SW: message received onMessage event (2): ${event.data}`,
clientId: client.id,
clientType: client.type,
clientUrl: client.url,
clientCount: clientCount
});
})
});
});
self.addEventListener('install', async (event) => {
console.log('on SW: install');
});
self.addEventListener('activate', async (event) => {
console.log('on SW: activate');
});
self.addEventListener('push', async (event) => {
const title = event.data.text();
await self.clients.matchAll().then(clients => {
const clientCount = clients.length;
console.log('clientCount =', clientCount);
clients.forEach((client, idx) => {
client.postMessage(title);
});
});
});
5. メモ
- Service Worker の一般的な状態変化:
installing
->installed
->activating
->activated
postMessage()
で ServiceWorker 側にメッセージを送るのは簡単だが、逆は適切なメソッドが用意されていない? Service Worker内で clients という変数が使えるが、現在のクライアントがその中のどれかなのか分からない?一斉にメッセージを送ることはできる。また、複数のブラウザで同一ページにアクセスしても、clients の要素数は 1だった。ServiceWorkerGlobalScope.clients
がいつセットされるのか分からない。- active(activating or activated) 以外の state の ServiceWorker に
postMessage()
を実行できるのか? - controller が変更した直後は、その controller となった ServiceWorker の state は、'activating' になっているようだ。
- Ctrl + Shift + R でリロードした場合、activated な ServiceWorker 内で、Clients が取得されない。キャッシュを使わせない場合だと、ServiceWorker とコンテキスト(windowなど)は紐付けられない?