Service Worker のまとめ

プログレッシブ ウェブアプリに興味があり、まずは Service Worker について調べたことをまとめてみました。

Service Workerとは

  • ブラウザが Webページとは別にバックグラウンドで実行するスクリプト。
  • プッシュ通知、バックグラウンド同期、オフライン機能などが提供されている。
  • オフライン機能では、AppCacheの問題点(複数ページで構成されたサイトでうまく動作しないなど)を改善するように設計されている。

Service Workerのポイント

  • JavaScript Workerの一つのため、DOMに直接アクセスできない。
  • 状態は、起動しているか、終了しているかの2つ。
    そのため、継続的にデータを Service Worker のライフサイクル間で共有したい場合は、IndexedDB API を使用してデータの保存・読み込みを行う必要がある。
  • JavaScript の Promises を多用する。
  • Httpsが必須(localhostではhttps://localhostでテストできる)。

Service Workerのライフサイクル

Webページとは異なるライフサイクルで動作する。

<ライフサイクル>
1. 対象のWebページにJavaScriptを登録
2. Service Workerのインストール
3. Service Workerののアクティベート
4. 起動か終了の状態になる

1. 対象のWebページにJavaScriptを登録

Service Workerをインストールするために、対象のWebページにService WorkerのJavascriptを登録する必要がある。

2. Service Workerのインストール

JavaScriptが登録されると、ブラウザは Service Worker のインストール処理をバックグラウンドで実行する。
インストール時の処理で、必要なファイルをキャッシュする。
もし、1ファイルでもダウンロードに失敗、もしくはキャッシュに失敗した場合、インストールは失敗する。

3. Service Workerののアクティベート

Service Workerが、スコープ内のすべてのページをコントロールできるようになる。
ただし、Service Worker を登録したページは、この時点ではコントロールできず、次回の読み込みでコントロールできるようになる。
また、不要なキャッシュは、アクティベート処理で削除する。

4. 起動か終了の状態になる

状態は起動・終了の2つのみ。
起動:fetch・message イベントによってService Workerは起動され処理を行う。
終了:メモリ節約のため、イベント処理の実施後は終了します。

Service Worker のスコープ

registerで登録したJavascriptが保存されている階層以下がスコープになる。(fetchイベントを受け付ける)

例)
register(/serviceworker.js)
ドメインルート以下の全てがスコープになる。

register(/hoge/serviceworker.js)
/hoge/ 以下の全てがスコープになる。

Service Worker のテスト

ブラウザのシークレットウインドウで行うのがオススメ。
シークレットウィンドは閉じると、登録やキャッシュが全て消去されるため、以前のテストの影響を受けなくすることができる。

Service Worker 登録のポイント

Service Workerの 登録 に使用する(register)は 、 複数回実行してもブラウザがインストール状態を確認してインストール済みの場合は、再インストールは行われない。

Service Worker インストールのポイント

キャッシュさせたいファイルがある場合は、インストールイベントで行う。
インストールイベントのコールバックを定義して、キャッシュさせたいファイルを指定します。

また、コールバック関数では、次のことを行います。

  • キャッシュを開く。
  • 必要なファイルをキャッシュする。
  • 必要なアセットがすべてキャッシュされたかを確認する。

Service Worker 更新のポイント

更新方法

Service Worker の Javascript ファイルを更新します。
ブラウザはサイトに移動した際に、Service Workerを定義するJSファイルを再ダウンロードしようとする。
実際にダウンロードするかの判断は、ブラウザが保持しているJSファイルと、サイトのJSファイルにバイト差異がある場合、新しいものと認識されダウンロードされる。

更新の流れ

1. ブラウザが 新しいService Workerが定義されているJSファイルをダウンロードすると、 Service Worker がスタートし、インストールイベントが発火する。

2. ただし、インストールイベントが発火してもすぐに 新しいService Worker が有効にはならない。
更新用のJSファイルをダウンロードしたページ自体は、古い Service Worker コントロールしているため、新しい Service Worker は waiting 状態になる。

3. このページが閉じられた時点で、古いService Worker は終了し、新しいService Worker がページをコントロールでき、activate イベントが発火する。

更新処理で行う処理

activateのコールバックで古いキャッシュの削除を行う。

理由

新しいService Workerをインストールしても、インストールを実施したページでは、古いService Worker が有効になっている。
そのため、新しい Service Worker は、インストールが完了しても、古い Service Worker が存在するため、 waiting状態になる。

仮に、新しい Service Worker のインストール時に、古いService Workerのキャッシュを削除してしまうと、古い Service Worker が本来必要としているキャッシュを提供できなくなる。

そのため、
キャッシュの登録:インストールのコールバック
キャッシュの削除:アクティベートのコールバック
で行うのが望ましい。

Service Workerがfetch を受け取るタイミング

Service Worker がインストールされた状態で、他ページヘ移動・ページの更新などで、Service Worker は fetch イベントを受け取る。

その他

ブラウザの実装状況を確認

is Serviceworker ready で確認できる。

https://jakearchibald.github.io/isserviceworkerready/

Service Worker が有効になっているかの確認

chromeのアドレスバーに以下を入力

chrome://inspect/#service-workers

Service Worker の詳細を確認

chromeのアドレスバーに以下を入力

chrome://serviceworker-internals
もしくは
chrome://inspect/#service-workers

まとめ

なかなか、ボリュームがある感じですがライフサイクルに気をつけて、各ステージで”何をすべきか”を考えて設計すると、そこまでハマらないような気がしました。

参考にさせていただいたサイト

https://developers.google.com/web/fundamentals/primers/service-workers/?hl=ja

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする