目录
一、SSR 是什么
1. CSR:客户端渲染
2. SSR:服务端渲染
二、SSR 的原理是什么
1. 浏览器发起请求
2. 服务器接收到请求
3. 服务端执行前端代码并生成 HTML
4. 服务器把 HTML 返回给浏览器
5. 浏览器下载 JS 并进行 Hydration
三、SSR 解决了什么问题
1. 首屏渲染慢的问题
2. SEO 问题
3. 更好的首屏体验
四、SSR 的典型工作流程
五、SSR 的常见坑
1. 服务端没有浏览器环境
解决方式
2. Hydration 不一致问题
后果
解决方式
3. 数据获取变复杂
4. 服务端压力更大
结果
应对
5. 缓存策略更复杂
6. 路由、状态管理要做“同构”
7. 样式处理更复杂
8. 第三方库兼容性问题
解决方式
9. 开发和部署复杂度上升
10. 安全问题更多
六、SSR 适合什么场景
七、SSR、CSR、SSG 的区别
1. CSR
2. SSR
3. SSG
八、面试回答模板
1. 先说原理
2. 再说解决的问题
3. 最后说坑
九、一句话总结
SSR =Server Side Rendering,服务端渲染。
你可以先记一句话:
SSR 就是在服务器先把页面 HTML 渲染好,再返回给浏览器,而不是只返回一个空壳 HTML 让浏览器自己渲染。
一、SSR 是什么
先看两个模式区别。
1. CSR:客户端渲染
这是普通前端 SPA 常见方式。
浏览器先拿到一个基础 HTML:
<div id="app"></div>然后再下载 JS:
- 请求数据
- 执行框架代码
- 渲染页面
- 挂载到
#app
也就是说,首屏内容主要靠浏览器执行 JS 后生成。
2. SSR:服务端渲染
浏览器请求页面时,服务器直接返回已经拼好的 HTML:
<div id="app"> <h1>商品详情页</h1> <p>价格:199</p> </div>浏览器一打开就能看到内容。
之后前端 JS 再接管页面,让它变成可交互应用,这一步叫:
Hydration / 水合
二、SSR 的原理是什么
SSR 的核心过程可以分成 5 步。
1. 浏览器发起请求
例如访问:
/product/10012. 服务器接收到请求
Node 服务拿到路由/product/1001,开始做两件事:
- 匹配当前访问的是哪个页面组件
- 拉取这个页面所需的数据
比如商品详情页要查商品信息。
3. 服务端执行前端代码并生成 HTML
服务器会运行前端框架代码:
- React:
renderToString - Vue:
renderToString
把组件 + 数据,直接渲染成完整 HTML 字符串。
例如:
<div> <h1>iPhone 15</h1> <p>售价:5999</p> </div>4. 服务器把 HTML 返回给浏览器
浏览器收到的是“有内容”的页面,所以首屏能直接展示。
5. 浏览器下载 JS 并进行 Hydration
虽然 HTML 已经有了,但只是静态内容。
还需要下载客户端 JS,把事件绑定上去,比如:
- 点击
- 输入
- 跳转
- 状态更新
这个过程叫水合。
也就是:
服务端负责“先显示”,客户端负责“变成交互页面”。
三、SSR 解决了什么问题
SSR 主要解决 3 类问题。
1. 首屏渲染慢的问题
CSR 模式下,页面展示依赖:
- 下载 JS
- 执行 JS
- 请求接口
- 渲染页面
如果 JS 很大、网络慢、设备差,就会出现:
- 白屏时间长
- 首屏慢
SSR 因为服务端已经把 HTML 生成好了,所以:
- 浏览器更快看到内容
- 用户感知首屏更快
2. SEO 问题
搜索引擎爬虫对页面的抓取,核心是抓 HTML 内容。
CSR 下,初始 HTML 常常是:
<div id="app"></div>正文内容是 JS 执行后才出来的。
有些搜索引擎对 JS 执行支持不好,可能抓不到真正内容。
SSR 返回的是完整 HTML,所以:
- 搜索引擎更容易抓到页面正文
- 更利于 SEO
尤其适合:
- 新闻站
- 博客
- 电商详情页
- 营销官网
3. 更好的首屏体验
SSR 页面打开时,用户能更快看到页面骨架甚至完整内容,而不是长时间白屏。
对于用户来说:
- 更快“看见”
- 感受更流畅
注意:
SSR 提升的是首屏可见速度和SEO,不一定代表整体交互一定更快。
四、SSR 的典型工作流程
可以这样理解:
请求到达服务器 -> 匹配路由 -> 拉取页面数据 -> 服务端渲染组件成 HTML -> 返回完整 HTML -> 浏览器展示 -> 浏览器下载 JS -> Hydration 绑定事件 -> 后续进入客户端路由模式很多框架其实都按这个思路做:
- Next.js
- Nuxt.js
- Remix
- 自建 React/Vue SSR
五、SSR 的常见坑
这部分是面试很爱问的重点。
1. 服务端没有浏览器环境
这是最常见的坑。
在服务端执行代码时,没有这些对象:
windowdocumentlocalStoragesessionStoragenavigator
所以如果你直接写:
window.localStorage.getItem('token');在 SSR 阶段就会报错:
window is not defined解决方式
只在客户端执行这些代码:
if (typeof window !== 'undefined') { localStorage.getItem('token'); }或者放到生命周期中,如 React 的useEffect、Vue 的onMounted。
2. Hydration 不一致问题
SSR 时服务端生成了一份 HTML,客户端也会根据同样组件重新生成一份虚拟结构来“接管”页面。
如果服务端渲染结果和客户端首次渲染结果不一致,就会出现 hydration warning。
比如:
<div>{Date.now()}</div>服务端时间和客户端时间不可能一样。
或者:
<div>{Math.random()}</div>每次渲染值都不同。
又或者根据浏览器环境渲染不同内容:
<div>{window.innerWidth}</div>服务端根本拿不到。
后果
- 控制台警告
- 页面闪动
- 事件绑定异常
- 某些节点被重新替换
解决方式
保证服务端和客户端首次渲染输出一致。
非确定性内容放到客户端挂载后再更新。
3. 数据获取变复杂
CSR 下通常是:
- 页面加载
- 发请求
- 渲染
SSR 下变成:
- 服务端先请求数据
- 把数据注入 HTML
- 客户端还要接管这份数据,避免重复请求
所以你需要处理:
- 服务端取数
- 客户端复用数据
- 路由切换后客户端再取数
- 错误页、超时处理
如果处理不好,就会出现:
- 服务端请求一次
- 客户端 hydration 再请求一次
- 重复请求
4. 服务端压力更大
CSR 更多计算发生在浏览器。
SSR 则要服务器做更多事:
- 路由匹配
- 数据请求
- 模板拼接
- 组件渲染
访问量大时,SSR 会明显增加服务端 CPU 和响应压力。
结果
- 并发能力下降
- 服务器成本变高
- 渲染慢时拖慢整体响应
应对
- 页面缓存
- CDN 缓存
- 微缓存
- 静态化/增量静态化
5. 缓存策略更复杂
SSR 页面往往是动态生成的,不像静态资源那样容易缓存。
你要考虑:
- 哪些页面可以缓存
- 哪些页面是用户个性化页面不能缓存
- 缓存多长时间
- 数据更新后如何失效
比如:
- 商品详情页可以短时间缓存
- 用户个人中心通常不能公共缓存
6. 路由、状态管理要做“同构”
所谓同构 / isomorphic,就是:
同一套代码既能在服务端运行,也能在客户端运行
比如全局状态管理时要注意:
- 服务端每个请求都应该创建独立 store
- 不能把 store 做成单例共享给所有用户
否则会出现:
A 用户的数据串到 B 用户页面里
这是 SSR 中非常危险的坑。
7. 样式处理更复杂
尤其是 CSS-in-JS、组件级样式方案。
SSR 时要解决:
- 服务端如何收集样式
- 首屏 HTML 如何带上关键样式
- 客户端如何正确接管
如果处理不好,会出现:
- 页面闪一下
- 样式丢失
- className 不一致
8. 第三方库兼容性问题
有些第三方库默认就是为浏览器写的,一加载就访问:
windowdocument
这在 SSR 环境就会直接炸。
解决方式
- 动态导入,仅客户端加载
- 替换成 SSR 兼容库
- 对库做环境判断
9. 开发和部署复杂度上升
SSR 不再只是前端静态资源部署,而是需要一个运行时服务。
意味着你要处理:
- Node 服务部署
- 服务监控
- 服务崩溃恢复
- 日志追踪
- 服务端路由与前端路由协作
相比纯静态 SPA,复杂度会高不少。
10. 安全问题更多
SSR 服务端渲染时会把数据拼进 HTML,如果处理不好,容易带来 XSS 风险。
例如把用户输入直接插入模板:
<script>window.__DATA__ = ${data}</script>如果没转义,可能被注入恶意脚本。
所以 SSR 注水数据时一定要做安全转义。
六、SSR 适合什么场景
适合:
- SEO 要求高的网站
- 首屏体验要求高的页面
- 内容展示型页面
- 营销页、官网
- 新闻、博客、电商详情页
不一定适合:
- 后台管理系统
- 强交互但 SEO 不重要的系统
- 登录后内部系统
因为后台系统通常:
- SEO 不重要
- 页面逻辑复杂
- SSR 带来的复杂度收益不高
七、SSR、CSR、SSG 的区别
1. CSR
浏览器拿到空壳 HTML,JS 渲染页面。
优点:
- 开发简单
- 前后端分离自然
缺点:
- 首屏慢
- SEO 差
2. SSR
每次请求时服务器动态渲染 HTML。
优点:
- 首屏更快
- SEO 更好
缺点:
- 服务端压力大
- 实现复杂
3. SSG
构建时提前生成静态 HTML。
优点:
- 性能最好
- SEO 好
- 部署简单
缺点:
- 不适合强实时动态内容
八、面试回答模板
你可以这样答:
1. 先说原理
SSR 就是服务端渲染。浏览器请求页面时,服务器会先根据当前路由获取数据,再执行前端组件代码,把页面渲染成完整 HTML 返回给浏览器。浏览器拿到 HTML 后可以直接展示首屏内容,然后再下载客户端 JS 对已有 HTML 做 hydration,绑定事件,让页面具备交互能力。
2. 再说解决的问题
SSR 主要解决两个核心问题:
第一是首屏渲染慢,CSR 需要等 JS 下载执行和接口返回后才能看到内容,而 SSR 可以更快把可见内容返回给浏览器;
第二是 SEO,SSR 返回的是完整 HTML,更利于搜索引擎抓取页面内容。
3. 最后说坑
SSR 的常见坑包括:服务端没有 window/document 等浏览器对象;服务端渲染和客户端首次渲染不一致会导致 hydration 问题;数据获取链路更复杂,容易重复请求;服务端渲染增加服务器压力;缓存策略、样式收集、第三方库兼容、同构状态管理等都会比 CSR 更复杂。
九、一句话总结
SSR 的本质是“服务器先产出 HTML,客户端再接管交互”;它主要解决首屏性能和 SEO 问题,但代价是同构开发、服务端压力和工程复杂度明显上升。