【イラスト付き】Servie Worker API【利用方法】
はじめに
皆さんこんにちは。
今回はServiceWorkerをご紹介します。
ServiceWorkerはオフライン動作、プッシュ通知、PWAなど様々な機能を実現する機能です。今回はServiceWorkerのライフサイクルやリクエストの横取りについて扱います。
今回の内容は次のような方にオススメです。
こんな人にオススメ
- ServiceWorkerの概要が知りたい
- ServiceWorkerの書き方が知りたい
初めて学習する方にも分かるように、要点を絞って丁寧に解説していきます。
😋 ServiceWorkerの全体像をご紹介します♪
ServiceWorkerとは
まずポイントをチェック
- Webアプリの制御を担当
- ブラウザにインストールされる
- メインスレッドとは別スレッドで動作
ServiceWorkerとはWebアプリの裏で動作し、Webアプリを制御する様々な機能を実装することができます。ビジネスロジックなどは持たず、裏でオフライン対応やプッシュ通知などの制御を行います。
ServiceWorkerは、Webアプリとは独立したライフサイクルを持ちます。ServiceWorkerはブラウザにインストールされることで有効化されます。インストールされたServiceWorkerはドメインごとに独立して管理されます。
😋 ServiceWorkerはブラウザにインストールされ裏側で動作します♪
利用ステップと最低限の実装
まずポイントをチェック
- ServiceWroker用のJSファイルを用意
- アプリのJSでServiceWorkerの利用開始の処理を記述
- 登録、インストール、有効化、の3ステップで利用開始
【準備1】ファイルの用意
ServiceWorkerの利用を開始するには、2つのファイルが必要です。アプリのファイルとServiceWorkerのファイルです。ServiceWorker用のJavaScriptファイルはアプリのルートフォルダに配置します。ServiceWorkerのファイルは何も書かないでOKです。
【準備2】登録処理
アプリのJavaScriptでServiceWorkerを登録する処理を記述します。navigator.serviceWorker.registerメソッドを使用し登録処理を行います。このメソッドは非同期で動作し、成功するとServiceWorkerがブラウザに登録されます。この状態はまだSurviceWorkerが有効化されていません。
navigator.serviceWorker.register(ServiceWorkerファイルパス);
【ServiceWorkerライフサイクル1】インストール
ServiceWorkerが登録されるとブラウザはServiceWorkerファイルをダウンロードします。ダウンロードし解析が完了するとnavigator.serviceWorker.registerメソッドのPromiseが解決されます。この時ServiceWorker側でinstallイベントが発生します。installイベントのリスナー関数の処理が完了すると、ブラウザはServiceWorkerをインストールした状態になります。ただしこの時点では有効化されていません。
【ServiceWorkerライフサイクル2】有効化
installイベントのリスナー関数の処理が完了すると、ServiceWorker側でactivateイベントが発生します。activateイベントのリスナー関数の処理が完了すると、ブラウザはServiceWorkerを有効化しServiceWorkerが動作開始します。
【ServiceWorkerライフサイクル3】制御の開始
有効化後、ServiceWorkerがWebアプリの制御を開始します。オフラインアプリケーションやプッシュ通知などに関するイベントが発生するようになります。
コードの全体像
// ServiceWorkerの登録
navigator.serviceWorker.register('sw.js');
// 最低限なのでinstallやactivateイベントの処理もなし
😋 ServiceWorkerファイルを用意し、登録して利用開始です♪
ServiceWorkerで発生するイベント
まずポイントをチェック
- ライフサイクル関連:install、activate
- 機能関連イベント:message、fetch、push、sync
ServiceWorkerの処理は特定のイベントをきっかけに行います。イベントリスナーの設定はselfを利用します。
self.addEventListener('イベント名', event => {XXXXX});
各イベントリスナーの概要を以下に説明します。
ライフサイクル関連のイベントは青色で表現しています。
- installイベント
- ServiceWorkerの初回登録時と更新時に発生
- オフライン時のリソースの収集を行う
- activateイベント
- ServiceWorkerが有効化される時に発生
- 旧バージョンのキャッシュの削除を行う
- messageイベント
- アプリのJSからメッセージを受信した際に発生
- WebアプリとServiceWorker間でのやり取りに利用
- fetchイベント
- WebアプリがHTTP通信を行った際に発生
- オフライン時のキャッシュ応答を行う
- pushイベント
- プッシュ通知を受信した際に発生
- プッシュ通知を表示する
- syncイベント
- ネットワークがオンラインに復帰した際に発生
- オフライン時の操作をオンライン復帰時に実施する
😋 中でもinstall、activate、fetchはよく利用します♪
fetchイベントの処理
まずポイントをチェック
- WebアプリがHTTP通信を行った際に発生
- リクエストを横取りしレスポンスすることができる
- キャッシュからレスポンスをする際に利用
fetchイベントはWebアプリがHTTP通信を行った際にServiceWorkerで発生します。fetchイベントで処理をすることで任意のレスポンスをWebアプリに返却することができます。つまりfetchイベントはリクエストを横取りするために使われます。
任意のレスポンスを返すにはrespondWithメソッドを利用します。fetchイベントのイベントオブジェクトから呼び出すことができます。引数はResponseオブジェクトかResponseに解決されるPromiseです。
// fetchイベントでリクストを横取りし、ダミーのレスポンスを返却
self.addEventListener('fetch', (event) => {
event.respondWith(new Response('ServiceWorkerでレスポンス'));
});
😋 fetchイベントで任意のレスポンスを返すことができます♪
ServiceWorkerの更新
まずポイントをチェック
- 次のステップで更新
- ServiceWorkerファイルを編集
- installイベントが発生
- 既存ServiceWorkerの制御対象がなくなるまで待機
- activateイベントが発生
ServiceWorkerファイルを変更することでServiceWorkerを更新することができます。ファイルを変更することでブラウザはServiceWorkerが更新されたことを検知します。
ServiceWorkerファイルが変更されると再度installイベントが発生し、新しいServiceWorkerがブラウザにインストールされます。初回インスール時とは異なり、更新時はinstallイベントの処理が終わってもすぐにactivateイベントは発生しません。
制御されているクライアントがなくなると新しいServiceWorkerでactivateイベントが発生し、有効化されます。
// Ver1
self.addEventListener('install', () => console.log('install Ver1'));
self.addEventListener('activate', () => console.log('activate Ver1'));
// Ver2 : Ver1をコメントアウトしてVer2を有効化し、更新を確認
// self.addEventListener('install', () => console.log('install Ver2'));
// self.addEventListener('activate', () => console.log('activate Ver2'));
😋 安定した動作を提供できるよう、更新時はすぐに有効化されません♪
ServiceWorkerのデバッグ
まずポイントをチェック
- 今回はChromeのデベロッパーツールを紹介
- デベロッパーツールで様々な開発機能を用意
- ServiceWorkerの明示的な更新
- 擬似的なオフライン化
- プッシュ通知の動作確認
ServiceWorkerのデバッグはブラウザのデベロッパーツールを利用します。いくつかの機能をご紹介します。今回はChromeを前提とします。
デベロッパーツールの開き方
- F12でデベロッパーツールを開く
- その他のツール > 開発者ツール をクリックしてもOK
- Applicationタブを開く
- ServiceWorker項目を開く
ServiceWorkerの即時反映
- 「再読み込み時に更新」にチェックをつけておく
ServiceWorkerファイルの内容を更新した際にすぐに反映されます。
オフラインの再現
- 「オフライン」にチェックをつけておく
擬似的にオフライン環境を実現可能できます。
プッシュ通知再現
- 事前に通知の許可をしておく
- URL欄の鍵アイコンを右クリック>サイトの設定>通知プルダウンで「許可する」を選択
- プッシュボタンを押す
ServiceWorkerにpushイベントのイベントリスナーを用意しておくことで動作確認ができます。
😋 デベロッパーツールでデバッグができます♪
おわりに
皆さん、お疲れ様でした。
ここまでご覧いただき、ありがとうございました。
ServiceWorkerについて確認をしていただきました。
独特なライフサイクルやWebアプリからのリクエストの横取りなど特徴的な仕様が多数あります。
ServiceWorkerはWebアプリとは独立して動作していため、少しイメージしづらいですが徐々に理解を深めていきましょう。
😋 これからもプログラミング学習頑張りましょう♪
参考リンク集(MDN Web Docs のリンク)
サービスワーカーの使用:https://developer.mozilla.org/ja/docs/Web/API/Service_Worker_API/Using_Service_Workers
サービスワーカー API:https://developer.mozilla.org/ja/docs/Web/API/Service_Worker_API
FetchEvent.respondWith():https://developer.mozilla.org/ja/docs/Web/API/FetchEvent/respondWith
Clients: claim() method:
参考リンク集(web.dev のリンク)
Service workers:https://web.dev/learn/pwa/service-workers/
Serving:https://web.dev/learn/pwa/serving/
The service worker lifecycle:https://web.dev/service-worker-lifecycle/
参考リンク集(その他 のリンク)
Introduction to Service Worker – Progressive Web App Training:https://www.youtube.com/watch?v=wEPeaJgbIxQ&list=PLNYkxOF6rcIB2xHBZ7opgc2Mv009X87Hh&index=7
Service Worker Debugging:https://www.chromium.org/blink/serviceworker/service-worker-faq/
参考リンク集(サンプルコード)
push-sample-with-notification(GitHub):https://github.com/ChanCode-Sample/JavaScript-API/tree/main/service-worker-sample
serviceworker-cookbook(MDN):https://github.com/mdn/serviceworker-cookbook
Discussion