2026 年的全栈前端,"在服务器上渲染"已经不是选择题,而是默认项。Next.js 15 把 React Server Components(RSC)从"实验特性"推到了生产主流,配合边缘计算(Edge Runtime),可以在离用户最近的节点渲染页面,TTFB 压到几十毫秒。

但 Server Components 的心智模型和传统 SPA 完全不同:哪些组件在服务端跑、哪些在客户端跑、数据怎么拿、缓存怎么控——踩过坑的人都知道,概念简单,落地不简单。本文基于生产经验,讲清楚 Next.js 15 + 边缘计算的正确姿势。

先搞懂分层:Server vs Client

Next.js 15 默认所有组件都是 Server Component(除非文件顶部写了 'use client')。两类组件的边界:

维度 Server Component Client Component
运行位置 服务器 / 边缘节点 用户浏览器
可访问 文件系统、数据库、密钥 DOM、localStorage、window
可包含交互 否(无 useState/useEffect)
打包进 JS 否(不发往客户端)

核心收益:Server Component 的代码不会出现在客户端 JS 包里。数据库查询、密钥、重型依赖都留在服务端,首屏 JS 体积大幅下降。

数据获取:在 Server Component 里直接 async

Server Component 最大的便利是组件本身可以是 async 函数,直接在里面 await 数据库或接口:

1
2
3
4
5
// app/posts/page.js — 这是一个 Server Component
export default async function PostsPage() {
const posts = await db.post.findMany() // 直接查库,不需要 API 路由
return <ul>{posts.map(p => <li key={p.id}>{p.title}</li>)}</ul>
}

不需要 getServerSideProps、不需要写 /api 路由、不用担心密钥泄露——数据获取和渲染在同一个函数里完成。这是 RSC 最大的开发体验提升。

缓存策略:Next.js 15 的四个层级

Next.js 15 的缓存体系是生产落地最容易踩坑的地方。四个层级从快到慢:

  1. 请求记忆(Request Memoization):同一次请求内,相同的 fetch 自动去重。同一渲染流程里 5 个组件都调了 fetch('/api/user'),实际只发 1 次。
  2. 数据缓存(Data Cache):跨请求、跨用户缓存 fetch 结果,持久化到磁盘。用 fetch(url, { next: { revalidate: 60 } }) 控制刷新频率。
  3. 全路由缓存(Full Route Cache):把整个页面的渲染结果缓存,默认对静态页面开启,动态页面按需关闭。
  4. 路由器缓存(Router Cache):客户端的内存缓存,导航回已访问页面时瞬间显示。

生产中最常用的是增量静态再生(ISR)

1
2
3
4
5
6
7
8
9
10
11
12
// 文章详情页:预渲染所有文章,每 60 秒重新验证一次
export const revalidate = 60

export async function generateStaticParams() {
const posts = await db.post.findMany({ select: { slug: true } })
return posts.map(p => ({ slug: p.slug }))
}

export default async function PostPage({ params }) {
const post = await db.post.findUnique({ where: { slug: params.slug } })
return <article>{post.content}</article>
}

ISR 兼具静态站的速度和动态站的新鲜度——用户看到的是预渲染的 HTML,内容过期后后台静默重新生成。

边缘计算:把渲染放到用户身边

Next.js 支持把 Server Component 部署到边缘运行时(Edge Runtime),在 Vercel、Cloudflare Workers、Netlify Edge 等全球节点执行。收益:

  • TTFB 极低:渲染在离用户最近的节点完成,不用回源到美国服务器;
  • 冷启动快:Edge Runtime 比 Node.js 冷启动快一个数量级;
  • 成本低:边缘函数按调用次数计费,无闲置成本。

代价是 Edge Runtime 不是完整 Node.js,不能用某些 Node 原生 API(如 fs、部分数据库驱动)。数据库访问要走支持 HTTP 的驱动(如 Prisma Accelerate、PlanetScale、Neon)。

生产建议:营销页、博客、文档站优先走边缘;需要重计算或访问本地文件的页面留在 Node.js 区域。一个项目里可以混用,按路由分配运行时。

实战中的关键决策

什么时候该用 Client Component

只有三种情况必须写 'use client'

  1. 需要 useState/useEffect 等交互 Hook;
  2. 需要访问 window/document/localStorage
  3. 用到了浏览器专属 API(如 Canvas、Web Audio)。

其他情况一律默认 Server Component,能显著减小客户端包体积。

Server Component 里别用浏览器 API

很多人踩坑:在 Server Component 里写了 typeof window 检测——服务端没有 window,这段代码永远走 false 分支。正确做法是把需要浏览器环境的逻辑拆到 Client Component,作为子组件嵌入。

避免把大对象从 Server 传到 Client

Server Component 给 Client Component 传 props 时,props 会被序列化进 HTML。传一个巨大的对象会让首屏 HTML 膨胀。原则:Server 端拿到数据后,只把 Client 真正需要的字段传下去,其余在服务端消费掉。

性能度量:关注这些指标

  • TTFB(首字节时间):边缘部署后应 < 100ms;
  • LCP(最大内容绘制):图片和字体优化后应 < 2.5s;
  • INP(交互到下一帧):Client Component 交互应 < 200ms;
  • JS 体积:开启 RSC 后首屏 JS 通常减少 40%~60%。

小结

Next.js 15 + Server Components + 边缘计算,把"服务端渲染"从"为了 SEO"升级成了"默认架构"。收益不只是更快的首屏,还有更小的客户端包、更安全的密钥管理、更简单的数据获取链路。落地时记住三条:默认 Server Component、用 ISR 控新鲜度、把无状态页面推到边缘。

相关阅读:前端性能的另一波进化在《React 19 + React Compiler》里;如果想了解浏览器原生能力的演进,可以看《WebAssembly 2026:在浏览器里获得原生级性能》。