在前端工程化的演进历程中,页面渲染方式始终是绕不开的核心话题。从最早的服务端模板渲染(JSP、PHP),到 AJAX 带来的 SPA 时代的客户端渲染,再到如今 SSR、SSG、ISR、Streaming SSR、RSC 百花齐放,每一种渲染模式的出现,都对应着特定场景下对性能、SEO、开发体验与服务器成本的权衡。
很多开发者面对 CSR、SSR、SSG、ISR、RSC、SPA、Streaming SSR 这些名词时,常常感到混淆:它们之间是什么关系?有何区别?各自适用于什么场景?技术选型时该如何决策?而 Hydration、JAMStack、群岛架构等衍生概念,更容易让知识体系变得零散。
这篇文章,我会用最直白的语言,把这些概念的本质、演化过程、相互关系和适用场景一次性讲清楚,帮你建立完整的渲染技术知识体系。
一、传统基石:MPA 与最早的“SSR”
在AJAX兴起之前,所有网站基本都是多页面应用(MPA, Multi-Page Application)。你点击一个链接,浏览器向服务器请求一个全新的HTML页面,服务器拼接好HTML(PHP、JSP、Rails等)后返回,浏览器完整刷新。
这其实就是最原始的服务端渲染(SSR)——HTML在服务器端动态生成,返回给客户端。它的特点很明显:
- 优点:首屏快(直接返回完整HTML)、SEO友好(爬虫能直接抓取内容)。
- 缺点:每次交互都整页刷新,用户体验割裂,服务器压力大。
那时的SSR是“无脑”的,没有同构、没有水合,页面是“死的”,JS只是添点特效。而真正的变革,要从SPA和CSR说起。
二、SPA 与 CSR:前端接管世界
随着浏览器性能提升和AJAX普及,单页面应用 (SPA, Single Page Application)出现了。
2.1 SPA(Single Page Application,单页应用)
SPA定义:单页应用是一种应用架构模式,整个应用只有一个 HTML 页面,页面切换通过前端路由动态渲染内容,而不会触发浏览器整页刷新。
核心原理:
- 首次加载时下载完整的 HTML、CSS、JS 资源
- 后续页面跳转由 JS 控制 DOM 替换与路由管理
- 通过 History API 或 Hash 路由模拟页面跳转
典型代表:React SPA(纯CSR模式)、Vue SPA(纯CSR模式)、Angular 应用
优点:
- 用户体验流畅,页面切换无刷新
- 前后端分离,开发效率高
- 服务器压力小,仅提供静态资源与 API
缺点:
- 首屏加载慢(白屏时间长)
- SEO 不友好(爬虫难以抓取 JS 渲染的内容)
- 首屏性能依赖客户端设备性能
注意:SPA 是一种应用架构,而非渲染模式。而实现SPA最直接的方式就是客户端渲染(CSR, Client-Side Rendering),但 SSR、SSG 等方案也可以构建 SPA 式的无刷新交互体验。
2.2 CSR(Client-Side Rendering,客户端渲染)
CSR定义:页面的核心内容由浏览器端的 JavaScript 运行后动态生成。服务器只返回一个几乎为空的 HTML 骨架,数据获取、模板解析、DOM 构建全部在客户端完成。
核心流程:
- 浏览器请求 HTML → 服务器返回空壳 HTML(只有一个根节点和JS引用)
- 浏览器下载并解析 JS Bundle
- JS 执行,请求 API 数据
- JS接管路由,数据返回后动态生成DOM并渲染页面
优点:
- 服务器压力极低,可托管于 CDN
- 前后端完全解耦,开发体验好
- 页面交互丰富,切换流畅
缺点:
- 首屏性能差,白屏时间长
- SEO 支持差,需要额外的预渲染方案
- 低端设备上渲染性能不佳
适用场景:后台管理系统、内部工具、强交互应用、对 SEO 无要求的页面。
SPA ≠ CSR,但早期SPA几乎都用CSR实现。 你可以认为SPA是一种应用架构模式(页面无刷新切换),而CSR是实现这种模式的一种渲染策略。
CSR的优缺点正好与MPA反转:
- 优点:交互丝滑,页面切换无白屏,前后端分离,开发体验好。
- 缺点:首屏白屏时间长(等JS下载执行完),SEO困难(爬虫看到的是空壳),对低端设备不友好。
为了解决CSR的致命伤,人们开始思考:能不能把服务端渲染的“快”和SPA的“活”结合起来?于是,现代SSR登场了。
三、现代SSR:同构渲染与水合(Hydration)
SSR(Server-Side Rendering,服务端渲染)
SSR定义:现代SSR与老派SSR完全不同。它指的是同构渲染:一套代码既可以跑在服务端生成HTML字符串,也可以跑在客户端接管交互。
在服务器端完成页面 HTML 的渲染工作,每次请求都实时生成完整的 HTML 字符串返回给浏览器。浏览器拿到 HTML 后可直接呈现内容,再配合 JS 注水(Hydration)获得交互能力。
核心流程:
- 浏览器发起页面请求
- 请求到达服务器,服务端运行React/Vue组件,获取数据,渲染组件为 HTML 字符串
- 服务器返回完整内容的 HTML
- 浏览器极快收到HTML,立刻展示首屏(首屏快,SEO好,此时已有内容,但无交互)
- 同时,浏览器在后台下载对应的JS bundle
- JS执行后,它不会重新生成DOM,而是“附着”到已有的服务端DOM上,绑定事件、激活响应式状态——这个过程叫水合(Hydration)。
- 水合完成后,页面变成一个活的SPA,获得交互能力,后续导航仍由客户端路由接管
优点:
- 首屏性能好,白屏时间短
- SEO 友好,爬虫可直接抓取完整 HTML
- 首屏内容不依赖客户端性能
所以,现代SSR实际上是将SPA的首屏渲染提前到了服务端,之后依然是一个SPA。 Next.js的getServerSideProps、Nuxt的asyncData就是典型实现。
缺点:
- TTFB可能变长:服务端渲染需要耗时,网络请求多的场景下TTFB会变慢。
- Time to Interactive(TTI)不一定提前:虽然首屏出现快,但页面要等到庞大JS下载、解析、水合完成后才能交互,这段时间用户点按钮可能是“假死”的。
- 服务器资源开销:每个请求都要动态渲染HTML,对服务器压力大于纯CSR(或纯静态)。
为了进一步压榨性能,SSG和ISR出现了。
四、SSG:把渲染提前到构建时
SSG(Static Site Generation,静态站点生成)
静态站点生成(SSG, Static Site Generation) 的思路非常直接:既然内容不频繁变动,为什么不在构建时就生成好HTML,直接当静态资源部署到CDN呢?
SSG定义:也叫预渲染(Pre-rendering)。在构建阶段(npm run build),框架(Next.js、Gatsby、Astro等)会拉取数据,渲染出所有页面的HTML,生成纯静态 HTML 文件,部署到 CDN 上。用户请求时直接返回已生成好的静态文件,无需服务器实时渲染。
核心流程:
- 构建时,遍历所有路由页面
- 提前获取数据,渲染生成完整 HTML 文件
- 静态资源部署到 CDN
- 用户请求时,CDN 直接返回对应 HTML
优点:
- 极致的性能(CDN边缘缓存,全球秒开),TTFB 极快,直接走 CDN
- 服务器成本最低,几乎无运行时计算
- SEO 友好,内容稳定可抓取
- 稳定性高,无服务端运行时故障风险
缺点:
- 构建时间随页面数量线性增长
- 内容更新需要重新构建部署,实时性差
- 不适合高度动态、千人千面的内容(如实时数据、用户仪表盘)
适用场景:博客、文档站、营销页、新闻资讯、电商商品详情页、内容更新不频繁的站点。
典型框架:Next.js(getStaticProps)、Nuxt.js(generate)、Gatsby、Astro、VitePress
五、ISR:让静态站点“活”起来
SSG的“重新构建才能更新”太僵硬了。增量静态再生(ISR, Incremental Static Regeneration) 由Next.js发扬光大,解决了这个问题。
ISR(Incremental Static Regeneration,增量静态再生成)
ISR定义:ISR允许你在不重建整个站点的情况下,对单个页面在运行时按需或定时重新生成静态HTML,并缓存起来。可以理解为“带过期时间的SSG,过期后首次请求触发后台静默再生”,兼顾静态性能与内容时效性。
核心原理:
- 构建时生成初始静态页面
- 设置 revalidate 时间(如 60 秒)
- 页面被访问时,若距离上次生成超过有效期,则在后台触发重新渲染
- 旧页面继续服务,新页面生成完成后自动替换
- 支持按需重新验证(On-demand ISR),通过 API 主动触发指定页面重建
优点:
- 保留 SSG 的 CDN 级性能
- 内容可定期更新,无需全量重建
- 构建时间可控,页面再多也不怕
- 兼顾 SEO 与动态性
缺点:
- 存在内容不一致窗口(stale-while-revalidate 机制)
- 首次访问过期页面的用户看到的仍是旧内容
- 高度动态场景仍不适用
适用场景:电商商品页、资讯列表、中等更新频率的内容页。
典型实现:Next.js ISR、Nuxt.js 的 Nitro 引擎也支持类似能力。
例如,一个电商站点,商品详情页数百万,全量构建不可能。使用ISR:
- 构建时只预渲染最热门的1000个商品页。
- 当请求一个未生成或已过期的商品页时,服务器先返回兜底页面(或旧缓存),同时后台触发渲染新页面。
- 新页面生成后替换旧缓存,后续请求就拿新静态页了。
ISR把SSG的边界拓展到了“内容变化不频繁,但不能接受完全重新构建”的场景,比如电商、社交媒体个人主页等。它本质是在CDN缓存层和服务器渲染之间找到了一个绝妙的平衡点。
六、Streaming SSR:不要等,先给用户看
传统的SSR,即使是同构,也是全量渲染:服务器必须把整个页面的HTML全部生成完毕,才能返回给浏览器。如果页面上某个组件的数据请求特别慢(比如复杂的数据库查询),整个页面都会被阻塞,导致TTFB极差。
流式SSR(Streaming SSR) 打破了这种阻塞。借助React 18的renderToPipeableStream和Suspense,服务器可以一边渲染,一边把已经就绪的HTML块通过HTTP流推送给浏览器。
Streaming SSR(流式服务端渲染)
Streaming SSR定义:SSR 的进阶形态。服务器不再等待整个页面渲染完成后一次性返回,而是将页面拆分为多个 chunk,边渲染边以流(Stream)的形式逐步发送给浏览器。
核心原理:
- 利用 HTTP 的分块传输编码(Transfer-Encoding: chunked)
- 页面骨架优先返回,内容区块陆续到达
- 浏览器可以边接收边解析渲染,无需等待完整响应
流程:
- 服务器立刻开始传输外层布局(Shell)。
- 遇到需要异步数据的部分(
<Suspense>包裹),先发送一个fallback占位符,然后继续渲染其他不依赖该数据的部分并传输。 - 当那个慢数据就绪后,服务器再流式推送该组件的真实HTML和一个小脚本,将其“填补”到占位符位置。
解决的痛点:
- 传统 SSR 的 TTFB 长问题:用户更早看到页面骨架
- 串行数据获取阻塞整个页面:非关键数据不阻塞首屏呈现
- 配合 Suspense 实现组件级流式渲染
优点:
-
首字节时间更短,用户感知更快
-
页面可逐步呈现,降低等待焦虑
-
支持组件级选择性 Hydration
-
缺点:
-
实现复杂度更高
-
对服务器流式处理能力有要求
-
SEO 场景下需确保爬虫能拿到完整内容
典型实现:React 18 的 renderToPipeableStream、Next.js App Router 的流式渲染、Vue 3 的 renderToNodeStream
这让首屏关键内容可以极速送达,而不被慢的部分拖累。结合HTTP/2多路复用,效果拔群。Streaming是SSR在性能上的关键进化。
七、RSC:对客户端JS的“减负革命”
RSC(React Server Components)
RSC定义:RSC 是 React 18 推出的全新组件渲染范式,允许组件在服务端运行并返回渲染结果,客户端只接收最终的 UI 描述(而非 JS 代码)。RSC 不是简单的 SSR,而是一种组件级的服务端 / 客户端混合渲染架构。
核心特性:
- 零 Bundle 体积:服务端组件的代码不会下发到客户端,显著减少 JS 体积
- 直接访问服务端资源:可直接读取数据库、文件系统、调用内部 API
- 自动代码分割:客户端组件边界自动成为代码分割点
- 与 Streaming SSR 天然配合:服务端组件可流式传输到客户端
工作模式:
- Server Component(服务端组件) :默认模式,在服务端执行,无交互能力,无生命周期,不能使用浏览器 API。永远只在服务端渲染(或在构建时),它不会被包含在客户端的JS bundle中。它可以直接访问数据库、文件系统等后端资源。它的输出不是HTML,而是一种特殊的可序列化格
- Client Component(客户端组件) :就是我们传统在浏览器中运行的交互组件(
'use client'),标记'use client',在客户端执行,保持水合和交互能力。 - 两种组件可互相嵌套,服务端组件可将数据作为 props 传给客户端组件
RSC 与传统 SSR 的区别:
| 维度 | 传统 SSR | RSC 架构 |
|---|---|---|
| 渲染粒度 | 页面级 | 组件级 |
| 下发内容 | HTML 字符串 | 特殊的序列化 UI 描述(RSC Payload) |
| Hydration | 全页 Hydration | 仅客户端组件需要 Hydration |
| JS 体积 | 完整 Bundle 下发 | 服务端组件代码不下发 |
| 数据获取 | 页面级集中获取 | 组件级各自获取 |
| 交互能力 | Hydration 后整体可交互 | 客户端组件独立获得交互 |
RSC 不等于 SSR! 你可以:
- 在SSG中使用RSC(构建时执行服务器组件,生成静态内容)。
- 在SSR中使用RSC(请求时执行服务器组件,动态生成)。
- 未来RSC甚至可以在客户端导航时(非页面刷新)被动态请求和渲染,实现类似“后端驱动UI组件”的效果。
它的核心价值是零客户端JS体积。一个纯展示的Markdown渲染组件,如果用服务器组件实现,它的库和逻辑完全留在服务端,客户端只收到结果UI,bundle大小显著下降。同时,它解决了传统“请求瀑布流”问题:服务器组件可以在一个地方、一次往返中直接拿到所有数据,而不需要客户端先渲染再发起多个API请求。
优势
- 大幅减少客户端 JS 体积,提升 TTI
- 数据获取更靠近数据源,减少网络瀑布流
- 开发体验统一,组件可自由选择运行环境
- 天然支持流式渲染与渐进式 Hydration
局限性
- 学习曲线陡峭,心智负担重
- 生态适配需要时间,第三方库需区分服务端 / 客户端
- 仅 React 生态原生支持,Vue 等框架有类似但不完全相同的实现
- 服务器成本高于纯静态方案
典型实现:Next.js App Router、Remix、Waku
RSC + Streaming SSR 的组合,就是现在Next.js App Router的核心范式:部分组件在服务端流式渲染,极小的客户端组件被精确水合,最终得到一个极快、极轻的SPA体验。
八、一张图看清概念关系
- SPA 是应用架构(无刷新)。
- CSR / SSR / SSG 是渲染发生的地点和时机。
- ISR 是SSG的增量缓存策略。
- Streaming 是SSR的性能优化手段(流式传输)。
- RSC 是一种新的组件分工模型,它决定了组件的运行环境(服务端/客户端)和输出物,可以和SSG、SSR、Streaming任意搭配。
| 概念 | 核心问题 | 渲染侧重点 |
|---|---|---|
| CSR | 谁渲染? | 客户端,JS执行后生成DOM |
| SSR | 谁渲染?什么时候? | 服务端,请求时动态生成HTML |
| SSG | 谁渲染?什么时候? | 构建时生成静态HTML,直接分发 |
| ISR | 静态页怎么更新? | 静态缓存 + 按需后台再生,是SSG的增强 |
| Streaming | HTML怎么更快到达? | 边渲染边流式传输,不等待全量完成 |
| RSC | 组件代码跑在哪? | 组件级别决定运行在服务器还是客户端,减少客户端JS |
| SPA | 页面怎么切换? | 应用架构,保证页面无刷新切换,是上述渲染的目标载体 |
| 特性 | CSR | 传统 SSR | Streaming SSR | SSG | ISR | RSC 架构 |
|---|---|---|---|---|---|---|
| 首屏速度 | 慢 | 中 | 快(感知) | 极快 | 极快 | 快 |
| TTFB | 快 | 慢 | 快 | 极快 | 极快 | 中 - 快 |
| SEO 友好度 | 差 | 好 | 好 | 极好 | 极好 | 好 |
| 服务器成本 | 极低 | 高 | 高 | 极低 | 低 | 中 - 高 |
| 内容实时性 | 实时 | 实时 | 实时 | 构建时 | 准实时 | 实时 |
| 开发复杂度 | 低 | 中 - 高 | 高 | 低 | 中 | 高 |
| 可交互时间 | 晚 | 中 | 中 - 早 | 早 | 早 | 早 |
| 适合页面数 | 不限 | 不限 | 不限 | 少量 - 中量 | 大量 | 不限 |
| CDN 友好 | 是 | 否 | 否 | 是 | 是 | 部分 |
它们不是互斥的,而是可以像积木一样组合。一个现代高性能应用通常是:
SPA架构 × (SSG + ISR) 用于内容页 × (SSR + Streaming + RSC) 用于动态页 × CSR 用于重交互部分
九、演进脉络:为什么会出现这么多渲染模式?
理解技术演进的逻辑,比死记概念更重要。我们可以把前端渲染的发展分为几个阶段:
阶段一:传统服务端渲染时代(JSP / PHP / ASP)
- 所有页面在服务端生成,浏览器只负责展示
- 前后端耦合,交互能力弱
- 本质就是最早的 SSR,但没有 Hydration 概念
阶段二:SPA + CSR 崛起(2012-2018)
- Angular、React、Vue 相继出现
- 前后端分离成为主流,开发效率大幅提升
- 但首屏性能与 SEO 问题逐渐暴露
阶段三:同构 SSR 回归(2016-2020)
- Next.js、Nuxt.js 等框架推动同构渲染普及
- 同一套代码既可在服务端渲染,也可在客户端 Hydrate
- 解决了 CSR 的首屏与 SEO 痛点,但带来服务器成本与复杂度
阶段四:静态化回归 SSG + ISR(2019-2022)
- JAMStack 概念兴起,静态站点重新受到重视
- 人们发现大部分页面其实不需要每次请求都渲染
- ISR 进一步弥补了 SSG 实时性不足的问题
阶段五:流式渲染与组件级服务端化(2022 至今)
- React 18 带来 Streaming SSR 与 Suspense
- RSC 将服务端渲染粒度从页面下沉到组件
- 目标是在保持 SSR 优势的同时,降低 JS 体积、优化 Hydration 成本
核心主线:始终在「首屏性能」「SEO」「开发体验」「服务器成本」「内容实时性」五个维度之间寻找最优平衡点。没有银弹,只有取舍。
十、相关概念补充:从属关系、核心关联与适用场景
先明确一个核心认知:上文提到的 CSR、SSR、SSG、ISR、Streaming SSR、RSC 属于「渲染模式层」,是页面内容生成的核心方式;而 SPA、JAMStack、群岛架构 属于「架构模式层」,是更高维度的应用组织范式;Hydration 系列、预渲染 则属于「优化技术层」,是依附于渲染模式的配套手段或增强策略。
它们并非同一维度的并列概念,而是存在明确的从属、支撑、优化关系。下面逐个拆解每个补充概念的定位、与核心渲染模式的关联、解决的痛点及适用场景。
10.1 Hydration(水合 / 注水)
维度定位:SSR / SSG / ISR 体系下的必备核心环节,不是独立渲染模式。
与核心概念的关联:
- 绑定出现:只要页面 HTML 是在服务端 / 构建时预先生成的(SSR、SSG、ISR、RSC 中的客户端组件部分),就必然需要 Hydration。
- 纯 CSR 不存在 Hydration:客户端渲染中,页面 DOM 本身就是 JS 生成的,事件和状态从一开始就绑定好了,只叫
render,不叫hydrate。 - RSC 的变化:RSC 架构中只有标记了
'use client'的客户端组件需要 Hydration,服务端组件永久不需要水合,这是 RSC 大幅减少 JS 体积的核心原因之一。
解决的核心问题: 服务端输出的 HTML 只是纯静态字符串,没有事件绑定、没有响应式状态、没有虚拟 DOM 映射。Hydration 就是客户端 JS 接管这份静态 HTML,重建组件树、绑定事件、恢复应用状态,让页面从「能看」变成「能用」的过程。
典型应用场景: 所有 SSR、SSG、ISR 项目的标配。只要你使用 Next.js、Nuxt.js 做服务端渲染或静态生成,页面加载后都会自动执行 Hydration。
传统全量 Hydration 的痛点: 默认情况下,SSR/SSG 采用全量水合—— 哪怕页面 90% 是纯静态文本,也要加载完整的组件 JS 并全量水合一遍,导致 JS 体积大、主线程阻塞久、页面可交互时间(TTI)偏晚。后续所有「XX Hydration」本质都是针对这个痛点的优化。
10.2 Partial Hydration(部分水合)
维度定位: SSR / SSG / ISR 的范围优化策略,是全量水合的直接替代方案。
与核心概念的关联:
- 核心思想:只给需要交互的组件做水合,纯静态内容永远保留为 HTML,不加载对应 JS 代码。
- 是 SSR/SSG 从「页面级渲染」走向「组件级精细化渲染」的第一步。
- 是群岛架构、RSC 的底层思想来源之一。
与全量 Hydration 的区别:
| 模式 | 水合范围 | JS 体积 | 实现复杂度 |
|---|---|---|---|
| 全量 Hydration | 整个页面所有组件 | 大 | 低(框架默认) |
| Partial Hydration | 仅标记为交互的组件 | 小 | 中 |
典型应用场景:
- 内容主导型站点:博客、资讯、新闻、电商商品详情页。这类页面大部分内容是静态展示(标题、正文、图片),只有少数模块需要交互(点赞按钮、评论区、规格选择器)。使用部分水合可以砍掉 70% 以上的首屏 JS 体积,显著提升 TTI。
代表实现: 早期的 react-lazy-hydrate、vue-lazy-hydration,以及 Astro 的群岛架构(极端化的部分水合)。
10.3 Progressive Hydration(渐进式水合)
维度定位: SSR / SSG / ISR 的时序优化策略,通常建立在 Partial Hydration 之上。
与核心概念的关联:
- 在「只水合部分组件」的基础上,进一步优化:按优先级分批次水合。
- 首屏关键交互组件(如购买按钮、导航栏)页面加载后立即水合;非关键组件(如底部推荐、评论区)延迟到浏览器空闲时(requestIdleCallback)或滚动进入视口时再水合。
解决的核心问题: 一次性水合所有交互组件仍然会阻塞主线程,导致首屏点击无响应。渐进式水合把水合任务拆碎,分散到多个空闲周期,优先保证首屏核心交互可用。
典型应用场景:
- 长页面、多模块的内容站或电商页。例如商品详情页:
- 立即水合:顶部导航、购买按钮、规格选择
- 空闲时水合:商品评价、相关推荐
- 滚动到视口水合:底部 footer、猜你喜欢
10.4 Selective Hydration(选择性水合)
维度定位: React 18 提出的并发式水合机制,与 Streaming SSR 深度绑定,是 React 生态独有的能力。
与核心概念的关联:
- Streaming SSR 的标配搭档:流式渲染让 HTML 可以分段到达,选择性水合让水合过程也可以分段、并发、可中断。
- 核心突破:传统 SSR 的水合是串行阻塞的 —— 某个组件没加载完,后面所有组件都得等。Selective Hydration 允许被 Suspense 包裹的组件延迟水合,不阻塞其他区域的水合和用户交互。
- 与 RSC 天然契合:RSC 架构下客户端组件本身就是独立边界,每个边界天然支持独立的选择性水合。
与 Progressive Hydration 的区别:
- Progressive Hydration 侧重「时间上的分批」,按时间顺序逐个水合;
- Selective Hydration 侧重「优先级调度与并发」,高优先级区域(用户点击的地方)可以插队优先水合,水合过程可被更高优先级任务中断。
典型应用场景: 复杂 SSR 应用、模块加载速度差异大的页面。例如数据看板 Dashboard:图表组件数据加载慢,但不会阻塞侧边栏、顶部搜索框先水合完成、响应用户输入;用户点击哪个模块,哪个模块就优先水合。
代表实现:
React 18 hydrateRoot + Suspense,Next.js App Router 默认开启。
10.5 Prerendering(预渲染)
维度定位: 通用技术手段,横跨 CSR 与 SSG,有广义和狭义之分。
与核心概念的关联:
- 广义:SSG 本身就是全站点预渲染,ISR 是增量式预渲染。所有「构建时 / 请求前先生成 HTML」的行为都可以叫预渲染。
- 狭义(行业常用) :特指 SPA 预渲染—— 给纯 CSR 的 SPA 项目打补丁,在构建时只渲染少数关键页面(首页、落地页)的静态 HTML,其余页面仍然走纯 CSR。
狭义预渲染与 SSG 的区别: 很多人会混淆二者,核心差异在于架构定位
| 维度 | SPA 预渲染 | SSG |
|---|---|---|
| 覆盖范围 | 通常只处理 3-5 个核心页面 | 全站所有路由都生成静态页 |
| 数据处理 | 一般只渲染静态骨架,不做复杂数据预取 | 构建时完整拉取数据并渲染到 HTML |
| 架构定位 | 给 SPA 做 SEO / 首屏优化的补丁 | 完整的站点渲染架构 |
| 改造成本 | 极低,几乎不用改业务代码 | 较高,需要按框架规范重构 |
典型应用场景: 存量 SPA 项目的低成本优化。比如一个用 React SPA 做的企业官网,不想大动架构迁到 Next.js,但需要首页、关于页能被搜索引擎抓取,且首屏白屏时间缩短。此时加一个预渲染插件即可,投入产出比极高。
代表工具: prerender-spa-plugin、React Snap、Puppeteer 预渲染方案。
10.6 JAMStack
维度定位: 前端架构理念 / 技术栈范式,不是具体的渲染模式。
与核心概念的关联:
- JAMStack = JavaScript + API + Markup,核心思想是:尽可能预渲染静态内容,动态能力通过客户端 JS 调用 API 实现,全站托管于 CDN。
- SSG 是 JAMStack 的核心渲染基石:Markup 部分由 SSG 在构建时生成;
- CSR 负责客户端交互:JavaScript 在浏览器端处理动态逻辑;
- ISR 是 JAMStack 的增强方案:解决纯 SSG 内容更新不及时的问题;
- 它不包含 SSR:JAMStack 推崇「无服务器」理念,尽量避免运行时服务端渲染。
典型应用场景: 营销站、博客、技术文档、电商商品展示页、企业官网。这类站点内容为主、动态交互少,适合静态化 + API 补动态能力。
优势: 极致性能、极低运维成本、高安全性、天然 CDN 加速。
10.7 Islands Architecture(群岛架构)
维度定位: 前端架构模式,是 Partial Hydration 思想的极致化落地。
与核心概念的关联:
- 页面主体:SSG 生成的纯静态 HTML(比喻为「海洋」);
- 交互部分:一个个独立的客户端组件(比喻为「岛屿」),每个岛屿本质上是一个微型 CSR 应用,独立加载、独立 Hydration、互不共享全局上下文。
- 本质:全局 SSG + 局部 CSR,是静态内容与客户端交互的混合范式。
与相关概念的关键区别:
-
与 Partial Hydration 的区别
- Partial Hydration:在同一个完整应用里,挑部分组件水合,共享全局状态和应用实例;
- 群岛架构:页面没有全局应用实例,每个岛屿是完全独立的前端应用,彼此隔离。
-
与 RSC 的区别
- 相同点:都是「服务端静态内容 + 客户端交互组件」的混合思路;
- 不同点:RSC 是同一个 React 应用内的组件分层,服务端组件和客户端组件在同一棵组件树里,可以无缝传参、共享上下文;群岛架构是多个独立应用的拼接,岛屿间通信困难,适合交互少且分散的场景。
典型应用场景: 重内容、轻交互的站点:媒体站、博客、营销落地页、文档站。交互模块少、分散且独立,不需要复杂的全局状态管理。
代表实现: Astro(首创者)、Marko、Fresh(Deno 生态)。
10.8 概念从属关系总览表
为了更直观地理清所有概念的层级和关联,整理一张全景对照表:
| 概念 | 所属层级 | 依附的核心渲染模式 | 核心作用 | 典型适用场景 |
|---|---|---|---|---|
| SPA | 架构模式 | CSR | 单页无刷新交互体验 | 后台系统、强交互应用 |
| JAMStack | 架构理念 | SSG / ISR + CSR | 静态优先、API 补动态 | 内容站、营销页 |
| 群岛架构 | 架构模式 | SSG + 局部 CSR | 极致静态化 + 按需交互 | 重内容、轻交互站点 |
| CSR | 渲染模式 | - | 客户端全量渲染 | 后台、内部工具 |
| SSR | 渲染模式 | - | 服务端实时渲染完整页面 | 强动态、强 SEO 页面 |
| Streaming SSR | 渲染模式 | SSR | 流式输出,优化感知性能 | 复杂 SSR 应用 |
| SSG | 渲染模式 | - | 构建时生成静态页 | 内容固定的站点 |
| ISR | 渲染模式 | SSG | 增量更新静态页 | 中等更新频率内容 |
| RSC | 渲染范式 | 可结合 SSR/SSG/Streaming | 组件级服务端 / 客户端分层 | 兼顾性能与交互的复杂应用 |
| Hydration | 核心环节 | SSR / SSG / ISR / RSC | 让预生成 HTML 获得交互 | 所有服务端渲染场景 |
| Partial Hydration | 优化策略 | SSR / SSG / ISR | 缩小水合范围,减 JS 体积 | 内容型站点 |
| Progressive Hydration | 优化策略 | SSR / SSG / ISR | 分时段水合,优先核心交互 | 长页面、多模块页面 |
| Selective Hydration | 优化策略 | Streaming SSR / RSC | 并发调度,水合可中断可插队 | React 复杂 SSR 应用 |
| Prerendering(狭义) | 优化手段 | CSR(SPA) | 给 SPA 补少量静态页 | 存量 SPA 的 SEO 优化 |
10.9 补充选型建议:什么时候该用这些进阶概念?
很多团队容易陷入「为了优化而优化」的误区,这里给出从业务出发的决策顺序:
- 如果是纯内部系统、对首屏和 SEO 无要求 用 SPA + CSR 即可,不需要任何 SSR/SSG,更不用考虑水合优化。
- 如果是内容站、SEO 重要、交互很少 优先 SSG;如果更新频繁就上 ISR。交互极少的情况下,全量 Hydration 开销也不大,不需要额外优化。
- 如果是内容站、有少量分散的交互模块 优先考虑 群岛架构(Astro) 或 Partial Hydration,用最小的 JS 代价实现交互。
- 如果是强动态页面、必须 SSR,且页面模块多、加载差异大 上 Streaming SSR + Selective Hydration,优化首屏感知速度和交互响应性。
- 如果是中大型应用,既看重 SEO / 首屏,又有大量复杂交互 考虑 RSC 架构(Next.js App Router) ,从组件层精细化控制服务端 / 客户端边界,平衡性能与开发体验。
- 如果是存量 SPA,只想补一下首页 SEO,不想大改 用 狭义预渲染,成本最低,见效最快。
核心原则:渲染模式和优化手段永远服务于业务。没有最好的技术,只有最适合场景的取舍。绝大多数中小站点,SSG + 轻量交互就足够支撑,不必盲目追求 RSC 等前沿方案。
十一、实践选型指南
别拿着锤子找钉子。选择依据无非三点:内容更新频率、交互复杂度、SEO/首屏要求。
- 纯营销落地页 / 博客:SSG 是王者。推送到CDN永世流传,零服务器运维。如果更新频繁,可以上ISR。
- 用户仪表盘、后台系统:这类根本不需要SEO,首屏快几毫秒意义不大。纯CSR SPA 足矣,开发效率最高,部署最简单。
- 内容为主,但有个性化数据的页面(如新闻带评论区):SSR + Streaming。先流式出文章主体,评论可以慢一点(Suspense包裹)。
- 电商商品详情页:经典ISR 场景。数百万SKU,大部分不常变,变动的价格库存用CSR水合。
- 重交互、SEO敏感、页面复杂:拥抱RSC + Streaming SSR。把数据密集、无交互的部分抽成服务器组件,交互部分保持客户端组件,获得最小的bundle和最快的交互准备。
选型的核心思考顺序:
- SEO 是否重要? → 否 → 优先 CSR
- 内容是否高度动态? → 是 → 考虑 SSR / Streaming SSR
- 内容更新频率如何? → 低 → SSG;中 → ISR;高 → SSR
- JS 体积与 TTI 是否敏感? → 是 → 考虑 RSC / Partial Hydration
- 服务器预算与运维能力? → 有限 → 优先 SSG / ISR;充足 → 可上 SSR / RSC
最后,一个容易被忽视的认知: 当我们说“SSR比CSR快”时,指的是首屏可见时间(FCP/LCP)。对于可交互时间(TTI),CSR的水合成本依然存在,甚至因为水合过程可能让TTI晚于纯CSR。RSC的愿景之一就是通过“零bundle组件”来消灭这种不必要的客户端成本。
十二、总结
前端渲染的演进史,就是一部在用户体验、开发者体验、服务端成本之间不断寻找最佳平衡的史诗。从MPA到SPA,从纯CSR到同构SSR,再到静态化、流式渲染、服务端组件,每一次迭代都是在解决上一个最优解带来的新问题。
- CSR 代表了极致的开发体验与动态能力,但牺牲了首屏与 SEO;
- SSR 补全了首屏与 SEO,但带来了服务器成本与复杂度;
- SSG 走向另一个极端,用静态化换取极致性能与低成本,代价是失去实时性;
- ISR 在 SSG 基础上往前一步,用增量更新平衡了静态性能与内容时效;
- Streaming SSR 优化了 SSR 的感知性能,让用户更早看到内容;
- RSC 则从架构层面重新定义了服务端与客户端的边界,是目前最前沿的探索方向。
理解这些概念,最重要的是抓住**“时间”(构建时?请求时?客户端运行时?)和“空间”**(服务端?客户端?CDN?)这两个维度。当你脑子里有了这个坐标轴,任何新技术都不过是坐标点上的一个更优解。
而 Hydration 系列优化、预渲染、JAMStack、群岛架构等概念,都是在核心渲染模式之上,针对特定痛点的增强与延伸。它们不是独立的替代品,而是工具箱里的不同工具,按需组合才能发挥最大价值。
没有任何一种方案是万能的。作为前端开发者,我们需要做的不是追逐最新技术,而是理解每种方案背后的权衡逻辑,根据业务场景做出最合适的选择。
希望这篇文章能帮你建立清晰的渲染模式知识体系。如果觉得有用,欢迎收藏分享。