発生した現象
WordPressが使われていたサイトでNext.js によりサイトのリニューアルをした
そのときトップページだけ通常アクセスや通常リロードで古いサイトが表示された
スーパーリロードすると新しいサイトが表示された
スーパーリロード後でも通常アクセスや通常リロードで古いサイトが表示された
ブラウザのdevtoolsにはページへのアクセスに対し Status Code:OK (from ServiceWorker)
が表示されていた
原因
旧サイトにServiceWorker(今回は /serviceWorker.js というリソース)があり、トップページやそのリソースをキャッシュし self.addEventListener('fetch'...
でレスポンスをキャッシュに差し替える処理が書かれていた
それがブラウザに登録された状態で新サイトに置き換わり、 /serviceWorker.js がなくなって 404 (from ServiceWorker)
になった
そしてServiceWorkerの仕様によると
新しい Worker は、ステータス コードが正常でないか(たとえば 404)、解析に失敗するか、実行中にエラーをスローするか、インストール時に棄却される場合は破棄されますが、現行の Worker はアクティブなままです。
ということなので、24時間更新チェックが走ろうともキャッシュを保持して返すWorkerはアクティブなまま残ったと思われる
原因の原因
WordPressのThe ThorというテーマにPWA設定があり、オンになっていた
これが /serviceWorker.js を設置していた
ダメな解決策
これらのどちらかで直るが、自分しか直らないので意味がない
解決策
以前あったのと同じServiceWorkerのファイルを作り、以下のように、全てのキャッシュを消してunregisterするような内容に置き換える
これにより、旧サイトにアクセスしたブラウザに登録されたServiceWorkerが新サイトにアクセスした時点で消える
if (navigator.serviceWorker) {
navigator.serviceWorker.getRegistrations().then(function (registrations) {
for (let registration of registrations) {
registration.unregister();
}
});
}
self.addEventListener('install', function (event) {
event.waitUntil(skipWaiting());
});
self.addEventListener('activate', function (event) {
event.waitUntil(self.clients.claim());
event.waitUntil(
caches.keys().then(function (cacheNames) {
return Promise.all(
cacheNames.map(function (cacheName) {
return caches.delete(cacheName);
}),
);
}),
);
});
感想
- ServiceWorkerのキャッシュ強すぎだろ…。24時間チェックで404になってたらunregisterしといてくれ
- WordPressの テーマに PWAの設定があり、設定されていたなんて予想外だった(自分がアタリをつけれたのはwordpressプラグインまでで、同僚が見つけてくれないと分からないままだった)。WordPressってそういうこともあるんですね
- 自分自身を
404 (from ServiceWorker)
と言ってるのを見たときはちょっと面白かった