ツー

日常の記録

Cloudfrontでキャッシュが全然切れないのはなんでかと思ったら、Reactが提供するPWA用のservice workerのせいだった

結論

create-react-app で作られたアプリで、index.js に書かれている registerServiceWorker()コメントアウトしておく。

既に呼んでいた場合は unregister() を呼ぶようにする。

経緯

Reactで作られたSPAアプリがあり、s3とCloudFrontで表示している。

ファイルを置くs3には aws s3 sync . s3://bucket として同期していたが、あるタイミングで aws s3 sync . s3://bucket --delete と変更し、古いファイルを消すようにした。

この修正以来、画面読み込み時にcssやjsが読み込まれずに画面が真っ白になる事象が出るようになった。

事象としては、普通に再読み込み(F5)するページが表示されずスーパーリロード(Ctrl+F5)するページが表示される

キャッシュが長いからかな?と思い CloudFront の TTL を短くしたり、Origin や Cache Behavior の設定をいじくり倒してみても改善せず。

なんでやと思いつつしばらく放置していたが、余裕ができたので調査を始めた。で、Developer toolsで表示をよく見ると

f:id:celeron1ghz:20210918162942p:plain

disk cache はよく見るものの、service worker ってなんやねんと思って調べたところ

Making a Progressive Web App | Create React App

デフォルトでPWA用にcacheの機構が入ってるらしい。話は聞いていたものの今回は悪さをしていた模様。

service workerは一度登録されるとサーバ側でどうにかできることではなく、一回 unregister() しないと古いままで残る。

なので下記のように index.js を修正しデプロイ。

import React from 'react'; // eslint-disable-line no-unused-vars
import ReactDOM from 'react-dom';
import Router from './route/Router';
// import registerServiceWorker from './registerServiceWorker';
import { unregister } from './registerServiceWorker';

import 'babel-polyfill';
import 'whatwg-fetch';
import 'url-polyfill';

ReactDOM.render(<Router />, document.getElementById('root'));
// registerServiceWorker();
unregister();

上記修正をした後、スーパーリロードを一回やれば、以降正常に表示されるようになった。

まとめ

Reactむずかしい。