🖥️
渲染模式
8 道题目
难度筛选:
CSR(Client-Side Rendering):浏览器下载空 HTML + JS Bundle,由 JS 在客户端动态生成页面内容。
工作流程:
1. 浏览器请求 HTML(几乎是空壳)
2. 下载并执行 JS Bundle
3. JS 在客户端生成 DOM 并渲染页面
4. 发起 API 请求获取数据并填充
优点:
• 交互体验好,页面切换无刷新(SPA)
• 服务器压力小(只提供静态文件)
• 前后端完全分离,开发效率高
缺点:
• 首屏加载慢(需等 JS 下载执行)
• SEO 不友好(爬虫看到空 HTML)
• 低端设备性能差时体验不佳
典型框架:React SPA、Vue SPA(Vue Router + history 模式)
工作流程:
1. 浏览器请求 HTML(几乎是空壳)
2. 下载并执行 JS Bundle
3. JS 在客户端生成 DOM 并渲染页面
4. 发起 API 请求获取数据并填充
优点:
• 交互体验好,页面切换无刷新(SPA)
• 服务器压力小(只提供静态文件)
• 前后端完全分离,开发效率高
缺点:
• 首屏加载慢(需等 JS 下载执行)
• SEO 不友好(爬虫看到空 HTML)
• 低端设备性能差时体验不佳
典型框架:React SPA、Vue SPA(Vue Router + history 模式)
查看答案即标记为已答
SSR(Server-Side Rendering):每次请求时,服务器执行 JS 生成完整 HTML 返回给浏览器。
工作流程:
1. 用户请求 URL
2. 服务器执行 React/Vue 代码
3. 获取数据、渲染组件为 HTML 字符串
4. 返回完整 HTML 给浏览器
5. 浏览器显示页面(用户可立即看到内容)
6. 下载 JS 并执行 Hydration(绑定事件,变为可交互)
优点:
• 首屏快(HTML 直接可显示)
• SEO 友好(完整 HTML 内容)
• 社交媒体分享预览正常
缺点:
• 服务器压力大(每次请求都渲染)
• TTFB 增加(服务器需要处理时间)
• 部署复杂(需要 Node.js 服务器)
• Hydration 可能导致" hydration mismatch"
工作流程:
1. 用户请求 URL
2. 服务器执行 React/Vue 代码
3. 获取数据、渲染组件为 HTML 字符串
4. 返回完整 HTML 给浏览器
5. 浏览器显示页面(用户可立即看到内容)
6. 下载 JS 并执行 Hydration(绑定事件,变为可交互)
优点:
• 首屏快(HTML 直接可显示)
• SEO 友好(完整 HTML 内容)
• 社交媒体分享预览正常
缺点:
• 服务器压力大(每次请求都渲染)
• TTFB 增加(服务器需要处理时间)
• 部署复杂(需要 Node.js 服务器)
• Hydration 可能导致" hydration mismatch"
查看答案即标记为已答
SSG(Static Site Generation):在构建时(build time)生成所有页面的 HTML 文件,部署到 CDN。
工作流程:
1. 构建时获取数据
2. 为每个页面生成静态 HTML 文件
3. 部署到 CDN / 静态服务器
4. 用户请求时直接返回 HTML(极快)
优点:
• 性能极佳(CDN 缓存,TTFB 极低)
• SEO 友好
• 服务器成本低(纯静态文件)
• 安全性高(无服务器攻击面)
缺点:
• 内容更新需要重新构建
• 不适合频繁变化的个性化内容
• 大型站点构建时间长
适用场景:博客、文档站、营销页、产品介绍页。
典型框架:Astro、Gatsby、Next.js(static export)、VitePress
工作流程:
1. 构建时获取数据
2. 为每个页面生成静态 HTML 文件
3. 部署到 CDN / 静态服务器
4. 用户请求时直接返回 HTML(极快)
优点:
• 性能极佳(CDN 缓存,TTFB 极低)
• SEO 友好
• 服务器成本低(纯静态文件)
• 安全性高(无服务器攻击面)
缺点:
• 内容更新需要重新构建
• 不适合频繁变化的个性化内容
• 大型站点构建时间长
适用场景:博客、文档站、营销页、产品介绍页。
典型框架:Astro、Gatsby、Next.js(static export)、VitePress
查看答案即标记为已答
ISR(Incremental Static Regeneration):在 SSG 基础上,支持后台按需重新生成静态页面,无需全站重新构建。
Next.js 中的工作方式:
1. 构建时生成初始静态页面
2. 用户请求时返回缓存的静态页面
3. 当缓存过期后(
4. 后台触发页面重新生成(stale-while-revalidate)
5. 下一个请求获得新生成的页面
按需重新生成(On-Demand ISR):
通过 API 调用
优点:静态页面的性能 + 动态内容的时效性,无需全站重建。
Next.js 中的工作方式:
1. 构建时生成初始静态页面
2. 用户请求时返回缓存的静态页面
3. 当缓存过期后(
revalidate 时间),先返回旧页面4. 后台触发页面重新生成(stale-while-revalidate)
5. 下一个请求获得新生成的页面
// Next.js Pages Router
export async function getStaticProps() {
const data = await fetchData();
return {
props: { data },
revalidate: 60, // 60秒后可重新生成
};
}按需重新生成(On-Demand ISR):
通过 API 调用
revalidatePath() 或 revalidateTag() 在内容变更时立即更新。优点:静态页面的性能 + 动态内容的时效性,无需全站重建。
查看答案即标记为已答
| CSR | SSR | SSG | ISR | |
|---|---|---|---|---|
| 渲染时机 | 客户端 | 请求时 | 构建时 | 构建+按需更新 |
| 首屏速度 | 慢 | 较快 | 极快 | 极快 |
| SEO | 差 | 好 | 好 | 好 |
| 服务器压力 | 低 | 高 | 极低 | 低 |
| 内容时效性 | 实时 | 实时 | 需重新构建 | 按需更新 |
| 部署复杂度 | 低 | 高(需Node) | 低(静态) | 中(需Serverless) |
选择建议:
• 博客/文档/营销页:SSG(内容不变,性能最优)
• 电商/新闻/博客平台:ISR(静态性能+内容更新灵活)
• 社交/仪表盘/个性化页面:SSR(数据实时,SEO 需要)
• 后台管理/工具应用:CSR(无需 SEO,交互优先)
现代趋势:一个应用中混合使用多种模式(Per-page Rendering Strategy)。
查看答案即标记为已答
Hydration(水合):SSR 输出静态 HTML 后,浏览器加载 JS,将静态 HTML "激活"为可交互的 SPA 应用。
过程:
1. 服务器返回完整 HTML(可显示但不可交互)
2. 浏览器加载 JS Bundle
3. 框架遍历 DOM 树,匹配虚拟 DOM
4. 绑定事件监听器,激活交互功能
常见问题:
1. Hydration Mismatch:服务端和客户端渲染结果不一致(如使用了
2. 重复工作:服务端已渲染,客户端又执行一遍(浪费)
3. 水合瀑布:必须下载当前路由的全部 JS 后才能开始水合
解决方案:
• React Server Components(RSC)— 服务端组件不需要水合
• Selective Hydration / Progressive Hydration — 按需/渐进式水合
• Resumability(Qwik)— 不需要水合,直接恢复
过程:
1. 服务器返回完整 HTML(可显示但不可交互)
2. 浏览器加载 JS Bundle
3. 框架遍历 DOM 树,匹配虚拟 DOM
4. 绑定事件监听器,激活交互功能
常见问题:
1. Hydration Mismatch:服务端和客户端渲染结果不一致(如使用了
Date.now()、Math.random())2. 重复工作:服务端已渲染,客户端又执行一遍(浪费)
3. 水合瀑布:必须下载当前路由的全部 JS 后才能开始水合
解决方案:
• React Server Components(RSC)— 服务端组件不需要水合
• Selective Hydration / Progressive Hydration — 按需/渐进式水合
• Resumability(Qwik)— 不需要水合,直接恢复
查看答案即标记为已答
Streaming SSR:服务端不等待整个页面渲染完成,而是分块(chunk)逐步将 HTML 流式传输给浏览器。
工作原理:
1. 服务端渲染页面骨架,立即发送给浏览器
2. 浏览器开始解析并显示已到达的部分
3. 数据就绪的组件渲染完成后,追加发送到 HTML 流中
4. 使用
React 18 实现:
优势:
• 更快的 TTFB:无需等所有数据
• 渐进式显示:先展示骨架,再填充内容
• 避免阻塞:慢组件不阻塞快组件
适用场景:页面中有多个独立数据区块,部分数据获取较慢时效果显著。
工作原理:
1. 服务端渲染页面骨架,立即发送给浏览器
2. 浏览器开始解析并显示已到达的部分
3. 数据就绪的组件渲染完成后,追加发送到 HTML 流中
4. 使用
<template> 插槽 + <script> 将内容插入正确位置React 18 实现:
renderToPipeableStream(<App />) + <Suspense>优势:
• 更快的 TTFB:无需等所有数据
• 渐进式显示:先展示骨架,再填充内容
• 避免阻塞:慢组件不阻塞快组件
适用场景:页面中有多个独立数据区块,部分数据获取较慢时效果显著。
查看答案即标记为已答
岛屿架构:页面大部分为静态 HTML(零 JS),只有交互区域(岛屿)注入 JS 并水合。
核心理念:
• 页面是"海洋"(静态 HTML)+ "岛屿"(交互组件)
• 每个岛屿独立水合,互不影响
• 非交互内容不加载任何 JS
vs 传统 SPA:
• SPA:整个页面都需要 JS 才能工作
• 岛屿:只有交互部分需要 JS
vs SSR + Hydration:
• 传统 SSR:整个页面都需要水合
• 岛屿:只水合交互组件,减少 JS 体积
代表框架:
• Astro — 默认零 JS,组件按需水合(client:load / client:visible)
• Fresh(Deno) — 默认不发送 JS 到客户端
• Marko — 细粒度部分水合
核心理念:
• 页面是"海洋"(静态 HTML)+ "岛屿"(交互组件)
• 每个岛屿独立水合,互不影响
• 非交互内容不加载任何 JS
vs 传统 SPA:
• SPA:整个页面都需要 JS 才能工作
• 岛屿:只有交互部分需要 JS
vs SSR + Hydration:
• 传统 SSR:整个页面都需要水合
• 岛屿:只水合交互组件,减少 JS 体积
代表框架:
• Astro — 默认零 JS,组件按需水合(client:load / client:visible)
• Fresh(Deno) — 默认不发送 JS 到客户端
• Marko — 细粒度部分水合
查看答案即标记为已答