SSR / SSG / ISR 完全指南:现代渲染策略的工程选型

"我们用 SSR 还是 SPA?""SSG 和 ISR 有啥区别?""流式渲染 RSC 是什么?" —— 现代 Web 应用的渲染策略选择越来越复杂。这篇文章把 SSR、SSG、ISR、CSR、流式渲染、Islands 架构讲透,讲清楚每种策略的适用场景和取舍。

渲染策略全家桶

CSR(Client-Side Rendering)

传统 SPA。服务端返回一个空 HTML + JS bundle,所有内容在浏览器执行 JS 后渲染。

<!-- 服务端返回 -->
<html><body><div id="root"></div><script src="app.js"></script></body></html>

优点:开发简单、交互流畅、SPA 体验。
缺点:首屏白屏长(等 JS 下载 + 执行)、SEO 差(爬虫看到空页面)、慢网络体验差。

SSR(Server-Side Rendering)

每次请求服务端渲染完整 HTML 返回,浏览器立刻显示内容,然后 hydrate(让 JS 接管交互)。

优点:首屏快、SEO 好。
缺点:服务端压力大、TTFB 慢(要等渲染)、复杂度高。

SSG(Static Site Generation)

构建时把所有页面预渲染成 HTML,部署后直接当静态文件分发(CDN)。

优点:极快(CDN 边缘节点直接返回 HTML)、零运行时成本、SEO 极好。
缺点:内容更新要重新 build(几百页面要几分钟)、不适合动态内容。

ISR(Incremental Static Regeneration)

Next.js 创新的混合策略 —— 页面静态预渲染,但设过期时间。过期后第一个请求触发后台重生成,旧 HTML 仍然立刻返回。下次访问看到新版本。

优点:SSG 的速度 + 部分 SSR 的新鲜度。
缺点:仍有"陈旧窗口",不适合实时数据。

选型决策

内容类型                推荐策略
博客文章 / 文档          SSG(几百到几千页面)
电商商品页 / 新闻        ISR(几万到几百万页面)
首页 / 营销页            SSG / ISR
用户 dashboard           SSR + hydration / CSR
实时数据                 CSR(WebSocket / SSE)
混合(静态 + 动态)       SSG/ISR + Client Components

Next.js App Router 实战

// Server Component(默认):服务端渲染,代码不到客户端
// app/blog/[slug]/page.tsx
export default async function Post({ params }) {
    const post = await db.getPost(params.slug);
    return (
        <article>
            <h1>{post.title}</h1>
            <p>{post.content}</p>
            <LikeButton postId={post.id} />   {/* Client Component */}
        </article>
    );
}

// 选择渲染策略:
// 1. 全静态(SSG)
export const dynamic = 'force-static';

// 2. 全动态(SSR)
export const dynamic = 'force-dynamic';

// 3. ISR
export const revalidate = 60;   // 每 60 秒后台重生成
// Client Component:在客户端跑,可以用 hooks
'use client';
import { useState } from 'react';

export function LikeButton({ postId }) {
    const [liked, setLiked] = useState(false);
    return <button onClick={() => setLiked(!liked)}>{liked ? '❤️' : '🤍'}</button>;
}

RSC:React Server Components

React 18 引入的革命性概念:组件可以在服务端运行,直接访问数据库,完全不下发给客户端。和 SSR 的区别:

  • SSR:组件代码仍然下发给客户端(hydrate 需要)。
  • RSC:服务端组件的代码不下发,只下发渲染结果。

结果:JS bundle 大幅缩小,首屏更快,数据获取直接在组件里写不用 useEffect + fetch。Next.js 13+ 的 App Router 全面拥抱 RSC。

流式渲染(Streaming SSR)

传统 SSR 要等整个页面渲染完才发回客户端。流式渲染让HTML 分块流式输出:

<Suspense fallback={<Spinner />}>
    <SlowComponent />     {/* 这部分慢,先发其他 */}
</Suspense>

# 浏览器接收顺序:
1. HTML 头 + 已经准备好的部分(立刻显示)
2. 慢组件准备好后,后续 HTML 流过来,React 自动填到 Suspense 位置

这让 TTFB 大幅改善 —— 页面骨架立刻显示,慢内容流式补充。

Islands 架构

Astro / Fresh / Marko 等新框架推动的思路:页面默认是静态 HTML,只有少数交互"岛屿"是 JS 组件

// Astro 例子
---
const posts = await fetchPosts();
---
<html>
<body>
    <h1>Blog</h1>
    {posts.map(p => <article><h2>{p.title}</h2></article>)}
    <ReactInteractive client:visible />   {/* 只有这个组件需要 JS,且滚动到才加载 */}
</body>
</html>

大多数内容是纯 HTML(零 JS 成本),交互组件按需 hydrate。极致性能,适合内容驱动的网站。

边缘渲染(Edge SSR)

SSR 不一定在中心服务器,可以在 CDN 边缘节点(Cloudflare Workers、Vercel Edge Functions、Fastly Compute):

  • 更接近用户,延迟更低。
  • 自动全球分发。
  • 限制:不能用 Node 全部 API(只有 V8 子集)、不能跑数据库长连接。

SEO 与渲染策略

Google 现在能执行 JS,理论上 SPA 也能被索引。但实践中:

  • Googlebot 的 JS 执行有限,大量内容仍可能漏抓。
  • 百度 / Bing 的爬虫对 JS 支持更弱。
  • 预渲染(SSR / SSG)对 SEO 最稳。

SPA 可以用动态预渲染(Rendertron、Prerender.io):检测到爬虫 UA 时返回服务端渲染版本,普通用户返回 SPA。但越来越多团队直接选 Next.js / Nuxt 等 SSR 框架,一步到位。

常见坑

坑 1:Hydration mismatch。服务端和客户端渲染结果不一致(比如服务端用了 new Date(),客户端再渲染时时间不同)—— React 警告 + 闪烁。规则:服务端和客户端共享的代码必须确定性。

坑 2:全部用 SSR。每个页面都 SSR,服务器压力翻 N 倍。可以静态的尽量静态。

坑 3:Server Component 里用浏览器 APIwindow 在服务端不存在。要么用 typeof 判断,要么标 'use client'。

坑 4:ISR 失败的处理。后台重生成失败时,旧页面继续返回 —— 但内容可能永远不更新。监控 revalidate 错误。

写在最后

2025 年的 Web 架构选择比五年前丰富得多。核心思路:能静态尽量静态,需要个性化才动态,需要交互才 hydrate。Next.js / Nuxt / Astro / Remix 这些现代框架都在朝这个方向走。选对策略比选对框架更重要 —— 选错了,框架再好也救不回来。

一图看懂

SSR / SSG / ISR 渲染时序一图看懂:

—— 别看了 · 2026
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理 邮箱1846861578@qq.com。
技术教程

Web 性能优化完全指南:从 Core Web Vitals 到 RUM 监控

2026-5-15 17:38:31

技术教程

微前端完全指南:从 qiankun 到 Module Federation 的实战

2026-5-15 17:38:32

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索