IT-Q

ページの隅にログインユーザー名を出したいだけです。そのために全体を動的にするのは避けたい。どうしますか。

ユーザー名を出す部分だけを別コンポーネントに切り出し、Suspense で包みます。cookies() の読み取りをページ先頭に書くとルート全体が動的になるためです。公式も同じ手を示しています。

面接官が見ているのはSuspense で境界を作る発想があるか。

これは「あるページだけビルド時に生成されず、毎リクエスト実行されていました。原因として何を疑いますか。」への追撃質問です。

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

  • その部分だけコンポーネントに切り出し、Suspense で包む
    公式が示している手そのものです。残りは静的なシェルとして先に返せます。
  • ユーザー名だけクライアント側から API で取りに行く
    成立しますし、実際よく使われます。ただし往復が1回増えますし、認証情報の扱いを別途考える必要があります。Suspense で済むならその方が素直です。
  • ページ全体を動的にしたうえで、キャッシュで速度を補う
    個人向けの内容を含むページをキャッシュするのは危険です。共有キャッシュに個人情報が入ると、他人のデータが見える事故になります。
  • layout でユーザー名を読む。page ではないので影響が出ない
    layout で読んでも同じです。むしろ配下の全ページに効くので影響は広がります。

面接官は何を見ているか

  • 該当部分だけコンポーネントに切り出すと答えた
  • Suspense で包む、と言えた
  • 残りは静的に保てると説明できた

模範解答

ユーザー名を出す部分だけを別コンポーネントに切り出し、Suspense で包みます。

公式も同じ手を書いています。cookies() や headers() の読み取りをページの先頭に書くとルート全体が動的になるので、その読み取りを Suspense の中のコンポーネントに移す。そうすると残りは静的なシェルとしてプリレンダーされ、動的な部分だけがリクエスト時にストリーミングされます。

考え方としては「ページ単位の全か無か」から「範囲を区切る」への移行です。ユーザー名の枠だけプレースホルダで出して、後から差し替わる形になります。

なお useSearchParams を使う Client Component も同様にSuspense 境界が必要です。検索パラメータもリクエスト時にしか分からないためです。

ここからどう深掘りされるか

この問いに答えられた場合、面談は次の質問に進みます。