Streaming(流式渲染)允许服务器逐步发送页面内容, 而不是等待所有内容准备好再一次性发送。使用 React 的 Suspense 边界, 可以让快速的部分先显示,慢速的部分稍后加载。
核心特性:
Suspense 实现📅 页面开始渲染时间:2025-12-17T09:54:12.778Z
这部分会立即发送给客户端(不等待下面的慢速组件)
下面的组件模拟了不同的加载时间。打开 Network 面板,查看 HTML 是如何逐步加载的。
这部分内容会立即渲染并发送,无需等待下面的异步组件。
加载时间:1000ms
完成时间:2025-12-17T09:54:13.779Z
加载时间:2000ms
完成时间:2025-12-17T09:54:14.779Z
加载时间:3000ms
完成时间:2025-12-17T09:54:15.779Z
过滤 "Doc" 类型,找到页面请求
在 Preview 或 Response 标签中,可以看到 HTML 是分块发送的
- 首先发送页面头部和立即显示的内容
- 然后逐步发送 Suspense 组件的内容
刷新页面,会看到:
1️⃣ 页面头部立即显示
2️⃣ 显示 3 个 loading 骨架屏
3️⃣ 1 秒后,组件 A 完成(替换骨架屏)
4️⃣ 2 秒后,组件 B 完成
5️⃣ 3 秒后,组件 C 完成
组件按顺序完成,每个组件完成时都会打印日志
// app/dashboard/page.tsx
import { Suspense } from 'react';
async function SlowComponent() {
const data = await fetchSlowData(); // 慢速 API
return <div>{data}</div>;
}
function LoadingUI() {
return <div className="animate-pulse">Loading...</div>;
}
export default function Dashboard() {
return (
<div>
{/* 立即显示的内容 */}
<h1>Dashboard</h1>
{/* 使用 Suspense 包裹慢速组件 */}
<Suspense fallback={<LoadingUI />}>
<SlowComponent />
</Suspense>
{/* 多个 Suspense 边界,独立加载 */}
<div className="grid">
<Suspense fallback={<LoadingUI />}>
<Stats />
</Suspense>
<Suspense fallback={<LoadingUI />}>
<Chart />
</Suspense>
</div>
</div>
);
}