ページの隅にログインユーザー名を出したいだけです。そのために全体を動的にするのは避けたい。どうしますか。
ユーザー名を出す部分だけを別コンポーネントに切り出し、Suspense で包みます。cookies() の読み取りをページ先頭に書くとルート全体が動的になるためです。公式も同じ手を示しています。
面接官が見ているのはSuspense で境界を作る発想があるか。
これは「あるページだけビルド時に生成されず、毎リクエスト実行されていました。原因として何を疑いますか。」への追撃質問です。
よくある答えと、面談でどう見られるか
- その部分だけコンポーネントに切り出し、Suspense で包む
公式が示している手そのものです。残りは静的なシェルとして先に返せます。 - ユーザー名だけクライアント側から API で取りに行く
成立しますし、実際よく使われます。ただし往復が1回増えますし、認証情報の扱いを別途考える必要があります。Suspense で済むならその方が素直です。 - ページ全体を動的にしたうえで、キャッシュで速度を補う
個人向けの内容を含むページをキャッシュするのは危険です。共有キャッシュに個人情報が入ると、他人のデータが見える事故になります。 - layout でユーザー名を読む。page ではないので影響が出ない
layout で読んでも同じです。むしろ配下の全ページに効くので影響は広がります。
面接官は何を見ているか
- 該当部分だけコンポーネントに切り出すと答えた
- Suspense で包む、と言えた
- 残りは静的に保てると説明できた
模範解答
ユーザー名を出す部分だけを別コンポーネントに切り出し、Suspense で包みます。
公式も同じ手を書いています。cookies() や headers() の読み取りをページの先頭に書くとルート全体が動的になるので、その読み取りを Suspense の中のコンポーネントに移す。そうすると残りは静的なシェルとしてプリレンダーされ、動的な部分だけがリクエスト時にストリーミングされます。
考え方としては「ページ単位の全か無か」から「範囲を区切る」への移行です。ユーザー名の枠だけプレースホルダで出して、後から差し替わる形になります。
なお useSearchParams を使う Client Component も同様にSuspense 境界が必要です。検索パラメータもリクエスト時にしか分からないためです。
ここからどう深掘りされるか
この問いに答えられた場合、面談は次の質問に進みます。
観点をすべて押さえられた場合
Suspense で包めば速くなる、という理解で合っていますか。