Streaming SSR 与 Suspense 粒度
cacheComponents 下的真实流式渲染:静态壳构建期预渲染先行吐出,三个不同时延的异步区块作为动态洞各自包 Suspense 分段到达;边界粒度决定谁阻塞谁
分段到达的三个区块
刷新页面观察:页头与骨架立即出现,三个区块按 0.5s / 1.5s / 3s 依次补出
快数据(0.5s)
等待数据中…
中速数据(1.5s)
等待数据中…
慢数据(3s)
等待数据中…
谁阻塞谁
Suspense 边界的粒度,决定了慢数据的爆炸半径
- 没有 Suspense 时:页面里最慢的那个 await 决定整页 TTFB,3s 的慢查询会让 0.5s 的快数据一起白屏等待
- 有了边界:静态壳(标题、导航、骨架)先流出去,浏览器立刻可渲染; 每个慢区块在自己的边界内独立 resolve,分段补出、互不相干
- 本页无需任何路由级配置:cacheComponents 下,Suspense 边界内 未缓存的 async 组件自动成为请求时渲染的动态洞,壳在构建期预渲染 —— build 输出里本页标为 ◐(Partial Prerender)。 旧模型(Next 15 及以前)要靠薄壳导出
dynamic = "force-dynamic"整页退出静态化,否则构建期拍平成静态 HTML,看不到流式效果 - dev 下观察方式:刷新页面看内容分段出现;或用
curl -N抓响应体,能看到 HTML 分 chunk 到达、尾部带着补洞的$RC脚本
什么时候别用 Streaming
决策要点,而非 API 背诵
- SEO 关键内容不要放进 Suspense 洞:爬虫对分段补出的内容收录不稳定,正文/标题必须随壳一起吐出
- 所有数据都很快(几十毫秒内)时,边界是多余的复杂度:壳与洞几乎同时到达,反而多一次渲染调度
- 数据间有强依赖(后一个查询要等前一个的结果)时,边界解决不了瀑布,先消依赖再谈分段