Streaming + Suspense — ページを一括ではなく部分ごとに配信する
Streaming + Suspense — ページを一括ではなく部分ごとに配信する
💡 なぜ学ぶ必要があるのか? — 最も遅いfetchがページ全体をブロックする
Suspense境界・loading.tsx・段階的ストリーミング
1. Suspense境界の動作原理
- ▸HeaderはすぐにHTMLとして送信されます。
- ▸ReviewsとRecommendのスロットはfallbackで埋められます。
- ▸各コンポーネントのfetchが完了すると、そのHTMLがその場にストリーミングされます(
</html>の閉じタグの後でも追加可能)。
2. loading.tsx — フォルダ単位の自動Suspense
ページ単位のローディング処理として最も手軽な方法。明示的なimportは不要。
3. 明示的な vs. loading.tsx
実務では両方を組み合わせて使用します。loading.tsxで大枠を、ページ内で
4. 段階的ストリーミングの視覚的効果
ユーザー体験:「何かすぐ表示された」(Header 0.1秒)→「レビューが来た」(0.3秒)→「おすすめも来た」(1秒)。旧来の方式なら1秒間の空白画面の後に一度に全て表示されるところが改善されます。
5. ウォーターフォールの回避 — 並列fetch+並列Suspense
6. エラー境界とのペアリング — error.tsx
App Routerではerror.tsxが自動的にErrorBoundaryの役割を担います。
💡 💡 Streaming + Suspense 実践5箇条
1. loading.tsxはページ全体、
ページの90%がデータ待ちであればloading.tsxで十分。一部だけが遅い場合は
2. Suspenseが捕捉するのは非同期サーバーコンポーネントのみ
クライアントコンポーネントのuseStateのデータはSuspenseでは捕捉されません(それはuseTransition / useDeferredValueの領域です)。
3. Suspense内のawaitは自動的にthrow → Reactが捕捉
明示的なthrowやtry/catchは不要。async functionをそのまま書くだけでOKです。
4. ウォーターフォールの回避 — 各コンポーネントが自身のデータをfetch
親ですべてのデータを集めてからpropsで子に渡すとウォーターフォールが発生します。各コンポーネントが自身のデータをfetchすると、Reactが並列処理します。
5. Suspense境界はErrorBoundaryとペアで使う
awaitがrejectされるとErrorBoundaryが捕捉します — Suspenseの内側ではなく外側で。App Routerのerror.tsxが自動的にこれを処理します。