Skip to main content

第86章:Streamingの“うれしさ”を体験する🌊✨

この章では「ページ全部が完成するまで待つ…😵」じゃなくて、できたところから先に見せる(=Streaming)を、実際に体験しちゃうよ〜!🥳 Next.js(App Router)は Suspense と組み合わせると、遅いパーツだけ後から差し込みできるんだ〜!🌊 (Next.js)


今日のゴール🎯💖

  • ✅ **Streamingって何が嬉しいの?**を体感する
  • ✅ **Suspenseで「遅い部品だけ後から表示」**を作れるようになる
  • ✅ 「あ、これなら待ち時間イライラ減る😆」ってなる

Streamingってなに?🌊(超ざっくり)

普通の表示だと、遅い処理(APIとかDBとか)があると 全部そろうまで画面が出ないことがあるよね🥲 でもStreamingだと…

  • 🟢 速い部分(ヘッダーとか説明とか) → 先に表示✨
  • 🟠 遅い部分(ランキングとかおすすめとか) → 後から到着して差し替え🌊

Suspenseは「ここはあとでOK!」っていう境界線を作る感じだよ〜🫧 (React)


図でイメージ🌈(Streamingの流れ)


ハンズオン🛠️:遅いランキングだけ「あとから出す」🌊📈

1) ルートを作る📁✨

app/streaming-demo/ を作って、まずこの2ファイルを用意してね👇

  • app/streaming-demo/page.tsx
  • app/streaming-demo/SlowRanking.tsx

2) page.tsx(速い部分+Suspense)を書く🏠🫧

// app/streaming-demo/page.tsx
import { Suspense } from "react";
import SlowRanking from "./SlowRanking";

function Card({
title,
children,
}: {
title: string;
children: React.ReactNode;
}) {
return (
<section
style={{
border: "1px solid #ddd",
borderRadius: 12,
padding: 16,
marginTop: 12,
}}
>
<h2 style={{ margin: 0, fontSize: 18 }}>{title}</h2>
<div style={{ marginTop: 10 }}>{children}</div>
</section>
);
}

export default function Page() {
return (
<main style={{ padding: 24, fontFamily: "system-ui, sans-serif" }}>
<h1 style={{ margin: 0 }}>🌊 Streaming 体験ページ</h1>
<p style={{ marginTop: 8 }}>
まずは上の部分がすぐ出て、ランキングだけ後から出るよ〜😆✨
</p>

<Card title="🍙 今日のおすすめ(速い)">
<ul style={{ margin: 0, paddingLeft: 18 }}>
<li>塩むすび</li>
<li>からあげ</li>
<li>味噌汁</li>
</ul>
</Card>

{/* 🌊 ここからがStreamingの主役! */}
<Suspense
fallback={
<Card title="📈 人気ランキング(読み込み中…)">
<p style={{ margin: 0 }}>⏳ ただいま集計中だよ〜…</p>
</Card>
}
>
<SlowRanking />
</Suspense>

<p style={{ marginTop: 18, opacity: 0.75 }}>
👉 ポイント:fallback(読み込み中)を先に表示しておいて、完成したら差し替える🌊
</p>
</main>
);
}

3) SlowRanking.tsx(わざと遅い部品)を書く🐢💤

// app/streaming-demo/SlowRanking.tsx
function delay(ms: number) {
return new Promise<void>((resolve) => setTimeout(resolve, ms));
}

export default async function SlowRanking() {
// わざと遅くする(3秒)
await delay(3000);

const ranking = [
{ name: "チキン南蛮", votes: 128 },
{ name: "オムライス", votes: 121 },
{ name: "カレー", votes: 119 },
];

return (
<section
style={{
border: "1px solid #ddd",
borderRadius: 12,
padding: 16,
marginTop: 12,
}}
>
<h2 style={{ margin: 0, fontSize: 18 }}>📈 人気ランキング(遅い)</h2>
<ol style={{ marginTop: 10, marginBottom: 0, paddingLeft: 18 }}>
{ranking.map((item) => (
<li key={item.name}>
{item.name}{item.votes}票)✨
</li>
))}
</ol>
<p style={{ marginTop: 10, opacity: 0.75 }}>
✅ ここは3秒後に“後から”届いて表示されるよ〜🌊
</p>
</section>
);
}

4) 動かして体験する🚀😆

ターミナルで👇

npm run dev

そしてブラウザで👇にアクセス🌈 http://localhost:3000/streaming-demo

見え方:

  • 最初に「Streaming体験ページ」「今日のおすすめ」がすぐ表示✨
  • 「人気ランキング(読み込み中…)」が出る⏳
  • 3秒後にランキングが スッ と表示されて差し替わる🌊😆

これが「Streamingのうれしさ」だよ〜!🥳 (Next.js)


うれしさポイント3つ💖

  • 🏎️ 体感が速い:全部待たなくていい
  • 🧩 遅いところだけ隔離できる:ページ全体が巻き込まれない
  • 🫧 ローディングUIを狙って置ける:ユーザーが安心する

Suspenseは「遅い部品のための待ち受け席」みたいな感じだね🪑✨ (React)


よくあるハマりどころ🪤😵‍💫(ここだけ注意!)

  • 😿 fallbackが出ない<SlowRanking /><Suspense>で包んでるかチェック!
  • 🧨 遅いコンポーネントに "use client" を付けちゃう → それだと「サーバーで待って後から差し込む」形が崩れやすいよ(まずはServerのままでOK)🧊
  • 🌀 開発モードだと挙動が分かりにくい時がある → その場合は npm run buildnpm start で試すと体感しやすいことがあるよ〜🔍✨(環境差はある)

ミニ課題🎓✨(10分でOK)

できたら超つよい💪💕

  • ⏱️ delay(3000)delay(6000) にして、待ち時間を伸ばしてみよう
  • 🧩 SlowRanking をもう1個作って、Suspenseを2つにしてみよう → 「ランキングAは先に来た!ランキングBはまだ!」みたいに分かれて表示されたら成功🌊✨

ここまでで、第86章はクリア🎉😆 「待ち時間=真っ白」じゃなくて、**“見せながら待つ”**ができるのがStreamingの強みだよ〜🌊💖