開発

Firebase Hostingで動的コンテンツのキャッシュを設定する

「Firebase HostingとCloud Functionsで動的コンテンツを配信した」
「アプリをデプロイし直したのに更新されない…キャッシュが原因か…!」
「管理画面だしキャッシュする必要ないんだよな、むしろデプロイのたびにすぐ更新されてほしい」

上記のような悩みでこの記事にたどり着いた方向けです。

ちなみに、前回の続きです。

Firebase Hostingで静的コンテンツのキャッシュを設定するFirebase、便利ですよね。Webサイトを簡単にホスティングできたり、サーバレス関数をでAPIを作ったり。 小〜中規模のプロダ...

Firebase Hostingでどのようにキャッシュ設定をするのかは前回解説したので、今回は実際の開発現場でも使えるキャッシュ設定をご紹介します。

Firebase Hostingで動的コンテンツをキャッシュする

おさらいですが、Firebase Hostingで静的コンテンツを配信する場合、デフォルトで1時間のキャッシュが保持されるよう設定されています。

一方、Cloud FunctionsやCloud Runと組み合わせて動的コンテンツを配信する場合、デフォルトでCDNではキャッシュされません。

そのため、動的コンテンツを配信する場合は開発者自身でキャッシュを設定する必要があるのです。

動的コンテンツのキャッシュの動作はユーザーが構成できます。たとえば、ある関数が新しいコンテンツを定期的に生成する場合は、生成されたコンテンツを少なくとも短期間キャッシュに保存することでアプリを高速化できます。

引用元:キャッシュ動作を管理する  |  Firebase

静的コンテンツの配信の場合、キャッシュ設定はfirebase.jsonに記述していましたが。

Cloud Functionsを用いて動的コンテンツを配信する場合、Cloud Functionsで作成する関数内のレスポンスヘッダーを設定します。

実際にどのように設定するのか見てみましょう。

Firebase Hosting + Cloud Functionsの動的コンテンツ配信で特定関数のレスポンスをキャッシュする

まずは手始めに特定関数へのリクエストにキャッシュを設定しましょう。

const functions = require('firebase-functions')
// アロー関数で定義しています
export const fetchUsers = functions.https.onRequest(async (req, res) => {
  // レスポンスヘッダーを設定する
  // クライアントに5分間、CDNに10分間、キャッシュを保持する
  res.set('Cache-Control', 'public, max-age=300, s-maxage=600')
  // データベースからユーザー情報を取得したと仮定する
  const users = await db.collection('users').get().then(snapshots => snapshots.forEach(snapshot => snapshot.data())
  // レスポンスを返す
  res.status(200).json({users: users})
})

 

res.set()でレスポンスヘッダーを設定しました。

設定可能な値はHTTPに準拠していますのでここでは解説を省略します。

Firebase Hosting + Cloud Functionsの動的コンテンツ配信で全てのレスポンスをキャッシュしない

全てのレスポンスをキャッシュしないことも可能です。この場合はfirebase.jsonに設定を記述します。

私はSPAで開発している管理画面の場合、以下のような設定にすることが多いです。

 

{
  "hosting": {
    "public": "build",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "headers": [
      {
        "source": "**",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "no-cache, no-store, must-revalidate"
          }
        ]
      },
      {
        "source": "**/*.@(css|png|svg|jpg)",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "max-age=7200"
          }
        ]
      }
    ],
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ]
  }
}

 

一部解説すると、rewritesルールによって全てのリクエストでindex.htmlを表示します。

ただし、SPAなのでJavaScriptによってルーティングを行い、URLに応じた画面を表示しています。

その際に、全てのリクエストでキャッシュを保持しないように”no-cache, no-store, must-revalidate”を設定します。

一方、CSSや画像などは一定期間キャッシュさせておきたいので、追記しています。

この設定にしておくとクライアント側にJavaScriptのキャッシュは保持されないため、SPAのアプリをビルド&デプロイした後すぐに反映されます。

以上がFirebase Hostingで動的コンテンツを配信する際のキャッシュ設定です。

Firebase HostingのCDN、つまりFastlyはstale-while-revalidateのヘッダーも使用できるので、工夫次第で効率的な配信が可能だと思います。

ぜひ試してみてください。

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

COMMENT

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

CAPTCHA