微雨暮色 發表於 2025-10-18 09:43:00

从0死磕全栈之Next.js 流式渲染(Streaming)实战:实现渐进式加载页面,提升用户体验 - 指南

<style>pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-size: 14px !important; line-height: 1.6 !important; padding: 16px !important; margin: 16px 0 !important; background-color: rgba(248, 248, 248, 1) !important; border: 1px solid rgba(225, 228, 232, 1) !important; border-radius: 6px !important; tab-size: 4 !important; -moz-tab-size: 4 !important; max-width: 100% !important; box-sizing: border-box !important }
code { font-family: "Consolas", "Monaco", "Courier New", monospace !important; font-size: 14px !important; white-space: pre !important; word-wrap: normal !important; word-break: normal !important; overflow-wrap: normal !important; display: inline !important; background: rgba(0, 0, 0, 0) !important; border: none !important; padding: 0 !important; margin: 0 !important; line-height: inherit !important }
pre code { background: rgba(0, 0, 0, 0) !important; border: 0 !important; border-radius: 0 !important; display: block !important; line-height: 1.6 !important; margin: 0 !important; max-width: none !important; overflow: visible !important; padding: 0 !important; white-space: pre !important; word-wrap: normal !important; word-break: normal !important; color: inherit !important }
.token.comment, .token.prolog, .token.doctype, .token.cdata { color: rgba(112, 128, 144, 1) !important; font-style: italic !important }
.token.punctuation { color: rgba(153, 153, 153, 1) !important }
.token.atrule, .token.attr-value, .token.keyword { color: rgba(0, 119, 170, 1) !important; font-weight: bold !important }
.token.function, .token.class-name { color: rgba(221, 74, 104, 1) !important; font-weight: bold !important }
.token.selector, .token.attr-name, .token.string, .token.char, .token.builtin, .token.inserted { color: rgba(102, 153, 0, 1) !important }
.token.property, .token.tag, .token.boolean, .token.number, .token.constant, .token.symbol, .token.deleted { color: rgba(153, 0, 85, 1) !important }
.cnblogs-markdown pre, .cnblogs-post-body pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; background-color: rgba(248, 248, 248, 1) !important; border: 1px solid rgba(225, 228, 232, 1) !important; border-radius: 6px !important; padding: 16px !important; margin: 16px 0 !important }
pre, pre, pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important }</style>
      <div class="markdown_views prism-atom-one-dark" id="content_views"><svg style="display: none" xmlns="http://www.w3.org/2000/svg"><path d="M5,0 0,2.5 5,5z" id="raphael-marker-block" stroke-linecap="round" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0)"></path></svg><blockquote><p>你是否遇到过页面“白屏几秒才出内容”的障碍?Next.js 的<strong>流式渲染(Streaming)</strong>功能,可以让你的页面像视频一样“边加载边显示”,用户无需等待全部信息就看到部分内容。本文通过一个简单例子,手把手教你用 App Router 实现渐进式加载。</p></blockquote><hr><h3>一、什么是流式渲染(Streaming)?</h3><p>在传统 SSR(服务端渲染)中,服务器必须<strong>等所有数据加载完</strong>,才能返回完整 HTML 给浏览器。用户看到的是“白屏 → 突然全屏内容”。</p><p>而 <strong>流式渲染</strong> 允许服务器<strong>分块发送 HTML</strong>:</p><ul><li>先返回页面骨架(如导航栏、标题)</li><li>再逐步填充信息区域(如文章内容、评论)</li></ul><p>✅ 用户感知更快,SEO 友好,体验更流畅。</p><blockquote><p> Next.js App Router 原生支持流式渲染,配合 React 18 的 <code>Suspense</code>,开箱即用!</p></blockquote><hr><h3>二、核心原理:<code>Suspense</code> + 异步组件</h3><p>Next.js 利用 React 18 的<strong><code>&lt;Suspense&gt;</code></strong>组件,将页面拆分为多个“可延迟加载”的区块。</p><p>结构如下:</p>
<pre style="white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important"><code class="prism language-jsx"><suspense fallback="加载中...">
   {/* 这个组件内部可以 await 数据 */}
</asynccomponent></suspense></code></pre>
<p>当 <code>AsyncComponent</code> 还在</p></div><br><br>
来源:https://www.cnblogs.com/yjbjingcha/p/19149240
頁: [1]
查看完整版本: 从0死磕全栈之Next.js 流式渲染(Streaming)实战:实现渐进式加载页面,提升用户体验 - 指南