yossydev Blog

Next.jsでBFCacheが有効化されない原因と解決方法

publishedAt:
2024/12/12
updatedAt:
2024/12/12
目次

2024年 ユウトの一人アドベントカレンダーの12日目の記事です。

Intro

Next.jsでBFCacheが有効化されなかった理由と解決方法について紹介します

サンプル

https://github.com/yossydev/nextjs-bfcache-playgroundというリポジトリを用意しています。

Content

BFCacheは検証ツールを見れば、なんでキャッシュされなかったのかわかるようになっています。 そして今回は、以下のようなものが見れました。

image
  • Pages with WebSocket cannot enter back/forward cache.
  • Back/forward cache is disabled because WebSocket has been used.
  • Pages whose main resource has cache-control:no-store cannot enter back/forward cache.

なんとなく、websocketと、cache-control:no-storeが機能していることが問題そうです。

WebSocket

これは筆者の凡ミスで、next devでローカルサーバーを起動してたことが問題でした。

検証ツールで表示されているファイルに飛んでみると、以下のようなコードに飛びます。

function connectHMR(options) {
    // ...etc
        source = new window.WebSocket("" + url + options.path); // エラーコード
}

ファイル名からもなんとなくわかる通り、HMR、つまりホットリロードです。 next devだとこの機能が使えるので、それがBFCache的にダメだったようです。

なのでこの解決法としては、next build && next startをすることで、

  • Pages with WebSocket cannot enter back/forward cache.
  • Pages whose main resource has cache-control:no-store cannot enter back/forward cache.

この二つは解消できます。

cache-control:no-store

二つ目です。これはWebsocketよりも直感的で、なんとなくエラー内容もわかりやすいです。

先ほど貼ったリポジトリを見ていただければわかるかと思いますが、今回筆者は特にキャッシュの設定などしていないです。(next.config.jsは除く) そのため、これはNext.js側で初回から設定しているものになります。

まぁ設定してあるのも納得ではあり、ユーザー情報などキャッシュしちゃダメなものを避けているのかなとも思います。 Next.jsからすればgetServerSidePropsはただapiとして提供しているだけなので、このapiを使ってどんな処理をSSRするかはわからないはずです。 ユーザー情報かもしれないし、今回のようなポケモンAPIかもしれない。

そうなってくると、no-storeでapi側は実装しておき、使用者の方でキャッシュしたければキャッシュするようにするのが確かに良いかもしれません。

さて、少し話がそれましたが、逆に言えば、今回のようなユーザー情報にか変わらないような処理はキャッシュしても良さそうです。

今回はだいぶ強引に、next.config.jsに一律キャッシュするように設定しました。

Result

ここまでで、以下のようにBFCacheが有効になってることがわかります。

image

まとめ

BFCacheが有効になった時、やはり明らかにページの遷移が早くなるのを実感できました。 あと、BFCacheはなんでキャッシュされなかったのかを検証ツールでわかりやすく教えてくれるのもいいですね。

0