JavaScript

React(CRA)で作ったアプリのキャッシュ制御【Firebase Hosting】

React(CRA)で作ったアプリのキャッシュ制御【Firebase Hosting】

「せっかく変更してデプロイしたのに変更が反映されていない…」
「Reactで作ったWebアプリの、PWAのキャッシュ設定がいまいち分からない」

という方向けの記事です。

前置き。

この記事の内容は2020/07/15時点で試行錯誤している段階です。
現在は備忘のために残しておき、解決したら修正します。

React(CRA)で開発したWebアプリのキャッシュにより変更が反映されない問題

ReactでWebアプリを開発しており本番運用もしているのだけれど、変更が反映されない問題が発生しました。

ブラウザのキャッシュをクリア(スーパーリロード)すると反映されるが、一般ユーザーはそんなことしてくれないですよね。。

なので対策を立てる必要がありました。

環境構成
  • create-react-app(CRA)で作成した開発環境
  • ホスティングサービスはFirebase Hostingを使用
  • Service Workerを設定している(PWA対応)

React(CRA)で開発したWebアプリのキャッシュを制御するためにやったこと

まず、Firebase Hostingの設定を見直しました。

Stack Overflowなどに記載されていた、Firebase Hostingの最強キャッシュクリア設定らしい。

firebase.json

"hosting": {
    "public": "build",
    "headers": [
      {
        "source": "**",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "no-cache, no-store, must-revalidate"
          }
        ]
      }
    ],
  },

 

ただしこの設定を入れても、iOS SafariとMac Safariでは変更が反映されないままでした。

Chromeは、MacもiOSも新規タブでWebアプリを開くと変更が反映されていました。

(その他デバイスやブラウザは確認できていません)

Service Workerによるキャッシュを疑ってみる

今回のWebアプリはPWA化するためにService Workerの設定をしていました。

設定、といってもCRAで作成されたserviceWorker.tsをそのまま使っています。
src直下のindex.tsxでは以下のようにserviceWorkerのregister()メソッドを呼び出しています。

src/index.tsx

import React from 'react'
import { render } from 'react-dom'
// 省略
import * as serviceWorker from './serviceWorker'


render(
    // 省略
    document.getElementById('root')
)

serviceWorker.register()

 

PWAだけに関連すると思っていたが、キャッシュを操作しているので、Service Workerが怪しいなあと思い、ドキュメントを読んでみる。

MozillaのPWAに関するドキュメントも読んでみる。

そしてCRAで作ったアプリをFirebase Hostingでデプロイするときは以下を設定せよ、というReactの公式ドキュメントも見つけた。

firebase.json

{
  "hosting": {
    ...
    "headers": [
      {"source": "/service-worker.js", "headers": [{"key": "Cache-Control", "value": "no-cache"}]}
    ]
    ...
}

 

「これは有力筋では?」と思ったけど、これを設定すると、iOS Safariでページを開こうとしてもずっとロード中になる…

 

結局、Service Workerを無効化することにしました。

src/index.tsx

import React from 'react'
import { render } from 'react-dom'
// 省略
import * as serviceWorker from './serviceWorker'


render(
    // 省略
    document.getElementById('root')
)

// unregister()に変更
serviceWorker.unregister()

 

そうすると、iOS/MacのSafariでも新規タブでWebアプリを開くと変更が反映されていました。

うーん、とりあえずキャッシュは残らなくなったものの、PWA対応できていないので調査を進めます。

ABOUT ME
稲垣 貴映
サーバーエンジニア兼Webフロントエンジニア。 新卒で独立系SIerに入社後、金融系システム基盤の構築・運用を3年間経験。 プログラミングを独学していた頃に、CEOの馬谷が開講していたSwiftスクールに通い、2019年9月に入社。 趣味はブラジル音楽の演奏。

COMMENT

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA