状況によっては、Service Worker がアクティブな 特定のイベントを知らせることができます。次に例を示します。
- Service Worker の新しいバージョンがインストールされたら、ページを通知して、 新機能にアクセスするための「更新して更新」ボタンをユーザーに表示する すぐに通知されます。
- Service Worker 側で行われたキャッシュ データの変更を、次の方法でユーザーに通知します。 「The app is now ready to work offline」、「 content available」と表示できます。
このようなユースケースを、Service Worker が Google Cloud からの コミュニケーション「最新情報のブロードキャスト」を開始できます。このガイドでは、Chronicle の ページと Service Worker 間でこのタイプの通信を実装するには、標準の ブラウザ API と Workbox ライブラリがあります。
本番環境のケース
Tinder
Tinder PWA は workbox-window
を使用してリッスンします
Service Worker のライフサイクルに関する重要な瞬間を
「有効」など)。こうすることで、新しい Service Worker が登場したときに「Update Available」と表示されます
バナーが表示され、ユーザーは PWA を更新して最新機能を利用できるようになります。
スクオッシュ
Squoosh PWA では、Service Worker が必要なすべての情報を オフラインで使用できるようにすると、ページに「オフラインで使用可」であることを示すメッセージがページに送信されます。 トーストし、その機能についてユーザーに知らせます。
<ph type="x-smartling-placeholder">ワークボックスの使用
Service Worker のライフサイクル イベントをリッスンする
workbox-window
は、Service Worker の重要なライフサイクルをリッスンできるわかりやすいインターフェースを提供します。
できます。
内部的には、ライブラリは次のようなクライアントサイド API を使用します。
updatefound
と statechange
また、workbox-window
オブジェクトで上位レベルのイベント リスナーが提供されるため、
イベントを使用できます
次のページコードを使用すると、新しいバージョンの Service Worker がインストールされるたびに、 これをユーザーに伝えることができます。
const wb = new Workbox('/sw.js');
wb.addEventListener('installed', (event) => {
if (event.isUpdate) {
// Show "Update App" banner
}
});
wb.register();
キャッシュ データの変更をページに通知する
Workbox パッケージ
workbox-broadcast-update
は、キャッシュされたレスポンスが更新されたことをウィンドウ クライアントに通知する標準的な方法を提供します。これは、
StalewhileRevalidate とともによく使用されるもの
戦略をご覧ください。
最新情報をブロードキャストするには、broadcastUpdate.BroadcastUpdatePlugin
Service Worker 側:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
import {BroadcastUpdatePlugin} from 'workbox-broadcast-update';
registerRoute(
({url}) => url.pathname.startsWith('/api/'),
new StaleWhileRevalidate({
plugins: [
new BroadcastUpdatePlugin(),
],
})
);
ウェブアプリでは、次のようにしてこれらのイベントをリッスンできます。
navigator.serviceWorker.addEventListener('message', async (event) => {
// Optional: ensure the message came from workbox-broadcast-update
if (event.data.meta === 'workbox-broadcast-update') {
const {cacheName, updatedUrl} = event.data.payload;
// Do something with cacheName and updatedUrl.
// For example, get the cached content and update
// the content on the page.
const cache = await caches.open(cacheName);
const updatedResponse = await cache.match(updatedUrl);
const updatedText = await updatedResponse.text();
}
});
ブラウザの API を使用する
Workbox の機能ではニーズを満たせない場合は、次のブラウザを使用してください 「ブロードキャスト アップデート」を実装するための API:
Broadcast Channel API
Service Worker が BroadcastChannel を作成する
オブジェクトが生成され、
追加できます。これらのメッセージの受信に関係のあるコンテキスト(ページなど)で、
BroadcastChannel
オブジェクトを作成し、メッセージを受信するためのメッセージ ハンドラを実装します。
新しい Service Worker のインストールをページに通知するには、次のコードを使用します。
// Create Broadcast Channel to send messages to the page
const broadcast = new BroadcastChannel('sw-update-channel');
self.addEventListener('install', function (event) {
// Inform the page every time a new service worker is installed
broadcast.postMessage({type: 'CRITICAL_SW_UPDATE'});
});
このページは、sw-update-channel
に登録することで、これらのイベントをリッスンします。
// Create Broadcast Channel and listen to messages sent to it
const broadcast = new BroadcastChannel('sw-update-channel');
broadcast.onmessage = (event) => {
if (event.data && event.data.type === 'CRITICAL_SW_UPDATE') {
// Show "update to refresh" banner to the user.
}
};
これは単純な手法ですが、ブラウザのサポートが限られています。このドキュメントの作成時点では、 Safari はこの API をサポートしていません。
Client API
Client API:
Service Worker から複数のクライアントと通信するには、
Client
オブジェクト。
次の Service Worker コードを使用して、最後にフォーカスされたタブにメッセージを送信します。
// Obtain an array of Window client objects
self.clients.matchAll(options).then(function (clients) {
if (clients && clients.length) {
// Respond to last focused tab
clients[0].postMessage({type: 'MSG_ID'});
}
});
このページには、これらのメッセージをインターセプトするメッセージ ハンドラが実装されています。
// Listen to messages
navigator.serviceWorker.onmessage = (event) => {
if (event.data && event.data.type === 'MSG_ID') {
// Process response
}
};
Client API は、複数のアクティブなタブに情報をブロードキャストする場合などに適しています。「 API は主要なブラウザでサポートされていますが、すべてのメソッドがサポートされているわけではありません。次の日付より前にブラウザのサポートを確認する できます。
メッセージ チャンネル
メッセージ チャネルの要件
最初の構成ステップとして、ページから Service Worker にポートを渡して、
通信チャネルを確立します。このページは MessageChannel
オブジェクトをインスタンス化し、
postMessage()
インターフェースを介して Service Worker にポートをルーティングします。
const messageChannel = new MessageChannel();
// Init port
navigator.serviceWorker.controller.postMessage({type: 'PORT_INITIALIZATION'}, [
messageChannel.port2,
]);
このページでメッセージをリッスンするために、ハンドラを実行します。
// Listen to messages
messageChannel.port1.onmessage = (event) => {
// Process message
};
Service Worker はポートを受け取り、そのポートへの参照を保存します。
// Initialize
let communicationPort;
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'PORT_INITIALIZATION') {
communicationPort = event.ports[0];
}
});
その時点から、postMessage()
を呼び出してページにメッセージを送信できます。
port:
// Communicate
communicationPort.postMessage({type: 'MSG_ID' });
MessageChannel
はポートを初期化する必要があるため、実装が複雑になる可能性がありますが、
すべての主要ブラウザでサポートされています。
次のステップ
このガイドでは、Window から Service Worker への通信の特定のケースについて説明しました。 "ブロードキャスト更新"。取り上げた例には、重要な Service Worker のリッスンが含まれます。 コンテンツの変更やキャッシュ データの変更に関するページへの通信も可能です。このように考えれば Service Worker がページとプロアクティブに通信する という興味深いユースケースがあります メッセージが送られてこないからです
ウィンドウと Service Worker の通信のその他のパターンについては、以下をご覧ください。
- 命令型キャッシュに関するガイド: ページから Service Worker を呼び出して 事前にリソースをキャッシュに保存します(プリフェッチのシナリオなど)。
- 双方向通信: タスクを Service Worker に委任する(例: 読み込みの負荷が大きくなるなど)、進行状況はページに継続的に報告されます。