Service Worker の状態変化テスト

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
  • Returns a service worker whose state is installing.
2 ServiceWorkerRegistration.waiting
  • Returns a service worker whose state is wating or installed.
  • 古い ServiceWorker が既に activated になっていて、新しい ServiceWorker が installed の状態で待ってることがある。
3 ServiceWorkerRegistration.active
  • Returns a service worker whose state is activating or activated.
- ServiceWorkerContainer.controller
(ServiceWorkerが更新されたら、こちらも更新される)
  • ServiceWorkerContainer.controller にセットされた ServiceWorker
  • 上の3つのうちのどれか1つがセットされているはず。
  • state が同じ ServiceWorker がセットされていると判断してよさそう。

3. コントロールパネル

ServiceWorkerRegistration.update() を実行する。




※ 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. メモ

Chrome DevTools の [Application]パネル

6. 参考