今回の記事は【ServiceWorker(A2HS)登録削除】【ServiceWorker独自キャッシュのクリア】を、閲覧者努力(ブラウザ設定をガチャガチャしたり、開発者モードでゴニョゴニョする)ではなく、サイト閲覧時に自動的に行うためのものです。
弊社サイトはブログコンテンツ実装前、【ServiceWorker】を使用して『Add to Homescreen(A2HS)』『オフライン対応』を実装しておりました。
その後、紆余曲折あり【ServiceWorker】を廃止して現在に至るわけですが、閲覧条件によって ServiceWorker独自キャッシュが残っており、古い画面が表示されるという不具合が発生しておりました。
その現象と同じくなるように検証環境を作成し、根本的な不具合を検証・解消した際の内容を記事にしてみました。
そもそもはオフライン環境でのアプリを実現・サポートするために作られたもので、Webページとは別にバックグラウンド(別スレッド)で動作する Javascript環境のことです。
ServiceWorker を使用することで『Add to Homescreen』『プッシュ通知』『バックグラウンドでのデータ同期』が可能になり、ファイルを先読みし独自キャッシュすることで、事実上オフライン環境での動作をサポートすることも可能となります。
※https 経由で配信されていることが動作条件となります(一応 localhost でも動きます)
※ブラウザが必要に応じて起動・終了するので、変数の値を保持できません
ブラウザ依存でショートカットを、閲覧者のホーム画面に追加・インストールすることができる機能のことです。
一般的には『ホーム画面に追加』『A2HS』と呼ばれるアレです。
下記の条件で、ServiceWorkerを認識するブラウザでのみ動作します。
任意指定したファイルをバックグラウンドで読み込むことで、オフラインになってもキャッシュされているファイル全てを表示・作動することが出来ます。
ここでいうキャッシュとは、通常のブラウザキャッシュとは別で、ServiceWorker独自のキャッシュを意味します。
Chrome であれば 開発者ツール > Application > CacheStorage で確認することが出来ます。
ServiceWorker自体が ssl環境でしか動きませんので、手軽に使える heroku にて『Add to Homescreen』『オフライン対応』を実装したサイトをサクっと構築
※ファイル先読みに関しては下記の方法が手軽で良い
STEP.1で作成したサイトに下記の施策を行った
navigator.serviceWorker.getRegistrations().then(function(registrations) {
for(let registration of registrations) {
registration.unregister();
}
});
当初、この施策により解決すると思っていたのですが…
ServiceWorkerの場合、通常のキャッシュとは別物で【ServiceWorker独自キャッシュ】が存在するようで…また、それはドメインに紐づいており ServiceWorker自体が削除されていても、条件によってはイキるようで古い画面が表示されました。
スーパーリロードすることで新しい画面に更新されましたが、画面遷移を繰り返すことで再度古い画面が表示されたりするという…完全にイケていない不具合。
STEP.2で施策したものに下記を追加
caches.keys().then(function(keys) {
let promises = [];
keys.forEach(function(cacheName) {
if (cacheName) {
promises.push(caches.delete(cacheName));
}
});
});
最終的に仕込んだ 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));
}
});
});