monolithic kernel

Firebase Hosting で GatsbyJS のサイトを配信するときのキャッシュ設定

December 27, 2019

    Netlify から Firebase Hosting に移行したときに適当に移植したキャッシュ周りの設定がおかしかったようだったので、改めてちゃんと設定し直した。

    まず、どのファイルにどういった設定をすべきかというのは GatsbyJS の以下のドキュメントを読めば分かる。

    これをどう Firebase の設定に落とし込めばいいかは Firebase のドキュメントを読めば当然分かる、と思ったんだけどあまりよく分からなかったので試行錯誤した。

    Firebase には、ローカルでサーバを立ち上げる firebase serve コマンドがあって、これを使うと試行錯誤もそこまで苦ではない。そして出来上がった設定ファイルのキャッシュ周りが以下の通り。

    {
        "hosting": {
            ...,
            "headers": [
                {
                    "source": "**",
                    "headers": [
                        {
                            "key": "Cache-Control",
                            "value": "public, max-age=0, must-revalidate"
                        }
                    ]
                },
                {
                    "source": "**/*.@(css|js)",
                    "headers": [
                        {
                            "key": "Cache-Control",
                            "value": "public, max-age=31536000, immutable"
                        }
                    ]
                },
                {
                    "source": "/static/**",
                    "headers": [
                        {
                            "key": "Cache-Control",
                            "value": "public, max-age=31536000, immutable"
                        }
                    ]
                },
                {
                    "source": "/@(sw.js|idb-keyval-iife.min.js)",
                    "headers": [
                        {
                            "key": "Cache-Control",
                            "value": "public, max-age=0, must-revalidate"
                        }
                    ]
                }
            ],
            ...
        }
    }

    ポイントは、記述した設定が上から順に評価されていって、マッチしたものはすべて適用される、その際同じヘッダがあったら下に書いた内容で上書きされる、といったあたりだろうか。このあたりは試してみないとよく分からなかった。分かってしまえば扱いやすい仕様ではある。

    idb-keyval-iife.min.js についてはドキュメントに明記されていなくてよく分からないものの、sw.js に付随するファイルであり、かつファイル名にハッシュ値を含まないことからキャッシュするのはこわいと考え、must-revalidate とした。

    あと、Netlify はセキュリティ関連のヘッダを勝手にいろいろ付けてくれるので、自分では明示的に指定していなかったのが、Firebase Hosting はそういうことはしてくれないので改めて指定する必要もあった。このサイトでは X-Frame-Options, X-XSS-Protection, X-Content-Type-Options, Referrer-Policy あたりを指定している。Strict-Transport-Security は勝手に付与してくれる様子。