IT-Q

キャッシュしないなら、そのぶん毎回遅くなりますよね。どう設計しますか。

全部する / しないではなく、データごとに鮮度要件で分けます。マスタ的なものはキャッシュしてよく、在庫数や残高のように古い値が事故になるものはキャッシュしません。

面接官が見ているのはキャッシュの判断とストリーミングを結び付けられるか。

これは「その fetch の結果はキャッシュされますか。」への追撃質問です。

よくある答えと、面談でどう見られるか

  • データごとに鮮度要件で分け、遅い部分は Suspense で切り出して先に他を見せる
    設計として筋が通っています。全部キャッシュするか否かの二択にしないところが要点です。
  • とりあえず全部キャッシュして、問題が出たら個別に外す
    順序が逆です。古いデータが出る事故は、出てからでは取り返しがつきません。キャッシュしないところから始めて、必要な箇所に入れる方が安全です。
  • ページ全体を Suspense で包んで、ストリーミングで返す
    包む位置が広すぎます。全体を1枚で包むと、結局全部揃うまで何も見えません。Suspense は「遅いものを含む最小の範囲」に置きます。
  • 表示に必要な分だけを取るようにクエリを見直す
    実はこれが一番効くことが多い解です。キャッシュもストリーミングも遅さを隠す手段で、取得自体を軽くするのは根本対処です。面談でも「隠す前に直す」と言える人は評価されます。

面接官は何を見ているか

  • データの鮮度要件で分ける、という基準を言えた
  • Suspense で切り出して他を先に見せる発想があった
  • 再検証(時間 / オンデマンド)に触れた

模範解答

「全部キャッシュする / しない」ではなく、データごとに分けます。

判断の軸は鮮度要件です。マスタ的なデータや更新が稀なものはキャッシュしてよく、在庫数や残高のように古い値を見せると事故になるものはキャッシュしません。

キャッシュしないデータがあるからといって、ページ全体を待たせる必要はありません。公式が挙げている手は2つで、"use cache" でキャッシュするか、取得しているコンポーネントを Suspense で包んでストリーミングするかです。後者にすれば、キャッシュ済みの部分を先に返して、遅い部分だけ後から流し込めます。体感としては「全部待つ」より大きく変わります。

キャッシュしたものをいつ捨てるかは、時間で切る方法と、更新処理の中から明示的に捨てる方法(オンデマンド再検証)の2通りです。更新経路が複数あると捨て漏れが必ず起きるので、経路が読み切れないうちは短めの時間指定で妥協する方が安全です。

なお、Suspense を挟む位置は「遅いものを含む最小の範囲」にします。ページ全体を1枚の Suspense で包むと、結局全部を待つのと変わりません。