North Detail / ノースディテール

BLOG ブログ

ブログ
CATEGORY
TECH

ServiceWorker をまるっと削除する方法(A2HS・オフライン対応・キャッシュ)

前書き・経緯

今回の記事は【ServiceWorker(A2HS)登録削除】【ServiceWorker独自キャッシュのクリア】を、閲覧者努力(ブラウザ設定をガチャガチャしたり、開発者モードでゴニョゴニョする)ではなく、サイト閲覧時に自動的に行うためのものです。

弊社サイトはブログコンテンツ実装前、【ServiceWorker】を使用して『Add to Homescreen(A2HS)』『オフライン対応』を実装しておりました。
その後、紆余曲折あり【ServiceWorker】を廃止して現在に至るわけですが、閲覧条件によって ServiceWorker独自キャッシュが残っており、古い画面が表示されるという不具合が発生しておりました。
その現象と同じくなるように検証環境を作成し、根本的な不具合を検証・解消した際の内容を記事にしてみました。

ServiceWorkerとは

そもそもはオフライン環境でのアプリを実現・サポートするために作られたもので、Webページとは別にバックグラウンド(別スレッド)で動作する Javascript環境のことです。
ServiceWorker を使用することで『Add to Homescreen』『プッシュ通知』『バックグラウンドでのデータ同期』が可能になり、ファイルを先読みし独自キャッシュすることで、事実上オフライン環境での動作をサポートすることも可能となります。
※https 経由で配信されていることが動作条件となります(一応 localhost でも動きます)
※ブラウザが必要に応じて起動・終了するので、変数の値を保持できません

Add to Homescreen

ブラウザ依存でショートカットを、閲覧者のホーム画面に追加・インストールすることができる機能のことです。
一般的には『ホーム画面に追加』『A2HS』と呼ばれるアレです。
下記の条件で、ServiceWorkerを認識するブラウザでのみ動作します。

  • manifest.json が適切に設定されていること
  • マニフェスト内の DisplayMode が standalone か fullscreen に設定されていること
  • サイトに ServiceWorker が登録されていること

オフライン対応

任意指定したファイルをバックグラウンドで読み込むことで、オフラインになってもキャッシュされているファイル全てを表示・作動することが出来ます。
ここでいうキャッシュとは、通常のブラウザキャッシュとは別で、ServiceWorker独自のキャッシュを意味します。
Chrome であれば 開発者ツール > Application > CacheStorage で確認することが出来ます。

検証環境を作成し施策・検証してみた

STEP.1:ServiceWorker実装

ServiceWorker自体が ssl環境でしか動きませんので、手軽に使える heroku にて『Add to Homescreen』『オフライン対応』を実装したサイトをサクっと構築

※ファイル先読みに関しては下記の方法が手軽で良い

ServiceWorkerPrecache

検証結果

  • 各ファイルは ServiceWorker から読み込まれた
  • CacheStorage に ServiceWorker独自キャッシュが生成された
各ファイルは ServiceWorker から読み込まれた
CacheStorage にキャッシュが作成された

STEP.2:ServiceWorkerの削除

STEP.1で作成したサイトに下記の施策を行った

  • ServiceWorker(javascript)を削除
  • manifest を削除
  • ServiceWorker登録の削除する javascript をサイト内に仕込む
navigator.serviceWorker.getRegistrations().then(function(registrations) {
  for(let registration of registrations) {
    registration.unregister();
  }
});

検証結果

  • 各ファイルは通常通り読み込みされた(deskCache・memoryCache)
  • CacheStorage に ServiceWorker独自キャッシュはそのまま残った
各ファイルは通常通り読み込まれた
CacheStorage にキャッシュは残ったまま

当初、この施策により解決すると思っていたのですが…
ServiceWorkerの場合、通常のキャッシュとは別物で【ServiceWorker独自キャッシュ】が存在するようで…また、それはドメインに紐づいており ServiceWorker自体が削除されていても、条件によってはイキるようで古い画面が表示されました。
スーパーリロードすることで新しい画面に更新されましたが、画面遷移を繰り返すことで再度古い画面が表示されたりするという…完全にイケていない不具合。

STEP.3:ServiceWorker独自キャッシュクリア

STEP.2で施策したものに下記を追加

  • ServiceWorker独自キャッシュを削除する javascript をサイト内に仕込む
caches.keys().then(function(keys) {
  let promises = [];
  keys.forEach(function(cacheName) {
    if (cacheName) {
      promises.push(caches.delete(cacheName));
    }
  });
});

検証結果

  • 各ファイルは通常通り読み込みされた(deskCache・memoryCache)
  • CacheStorage の ServiceWorker独自キャッシュは削除された
各ファイルは通常通り読み込まれた
CacheStorage からキャッシュが消えた!

これでようやく目指す挙動となりました!

最終的に仕込んだ javascript は下記になります。
この記事がどこかの誰かの手助けのヒントのカケラになることを祈って( ̄^ ̄)ゞ

navigator.serviceWorker.getRegistrations().then(function(registrations) {
  for(let registration of registrations) {
    registration.unregister();
  }
});
caches.keys().then(function(keys) {
  let promises = [];
  keys.forEach(function(cacheName) {
    if (cacheName) {
      promises.push(caches.delete(cacheName));
    }
  });
});
nanba
WRITER:nanba
高い技術力を誇る『NorthDetail』内では珍しい『チカラワザ系コーダー』
主な記事 一覧へ

一覧へ

IS 501383 / ISO 27001