55、ssr 的原理是什么?解决了什么问题?ssr 会有哪些坑?

张开发
2026/4/15 12:59:22 15 分钟阅读

分享文章

55、ssr 的原理是什么?解决了什么问题?ssr 会有哪些坑?
目录一、SSR 是什么1. CSR客户端渲染2. SSR服务端渲染二、SSR 的原理是什么1. 浏览器发起请求2. 服务器接收到请求3. 服务端执行前端代码并生成 HTML4. 服务器把 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. CSR2. SSR3. SSG八、面试回答模板1. 先说原理2. 再说解决的问题3. 最后说坑九、一句话总结SSR Server Side Rendering服务端渲染。你可以先记一句话SSR 就是在服务器先把页面 HTML 渲染好再返回给浏览器而不是只返回一个空壳 HTML 让浏览器自己渲染。一、SSR 是什么先看两个模式区别。1. CSR客户端渲染这是普通前端 SPA 常见方式。浏览器先拿到一个基础 HTMLdiv idapp/div然后再下载 JS请求数据执行框架代码渲染页面挂载到#app也就是说首屏内容主要靠浏览器执行 JS 后生成。2. SSR服务端渲染浏览器请求页面时服务器直接返回已经拼好的 HTMLdiv idapp h1商品详情页/h1 p价格199/p /div浏览器一打开就能看到内容。之后前端 JS 再接管页面让它变成可交互应用这一步叫Hydration / 水合二、SSR 的原理是什么SSR 的核心过程可以分成 5 步。1. 浏览器发起请求例如访问/product/10012. 服务器接收到请求Node 服务拿到路由/product/1001开始做两件事匹配当前访问的是哪个页面组件拉取这个页面所需的数据比如商品详情页要查商品信息。3. 服务端执行前端代码并生成 HTML服务器会运行前端框架代码ReactrenderToStringVuerenderToString把组件 数据直接渲染成完整 HTML 字符串。例如div h1iPhone 15/h1 p售价5999/p /div4. 服务器把 HTML 返回给浏览器浏览器收到的是“有内容”的页面所以首屏能直接展示。5. 浏览器下载 JS 并进行 Hydration虽然 HTML 已经有了但只是静态内容。还需要下载客户端 JS把事件绑定上去比如点击输入跳转状态更新这个过程叫水合。也就是服务端负责“先显示”客户端负责“变成交互页面”。三、SSR 解决了什么问题SSR 主要解决 3 类问题。1. 首屏渲染慢的问题CSR 模式下页面展示依赖下载 JS执行 JS请求接口渲染页面如果 JS 很大、网络慢、设备差就会出现白屏时间长首屏慢SSR 因为服务端已经把 HTML 生成好了所以浏览器更快看到内容用户感知首屏更快2. SEO 问题搜索引擎爬虫对页面的抓取核心是抓 HTML 内容。CSR 下初始 HTML 常常是div idapp/div正文内容是 JS 执行后才出来的。有些搜索引擎对 JS 执行支持不好可能抓不到真正内容。SSR 返回的是完整 HTML所以搜索引擎更容易抓到页面正文更利于 SEO尤其适合新闻站博客电商详情页营销官网3. 更好的首屏体验SSR 页面打开时用户能更快看到页面骨架甚至完整内容而不是长时间白屏。对于用户来说更快“看见”感受更流畅注意SSR 提升的是首屏可见速度和SEO不一定代表整体交互一定更快。四、SSR 的典型工作流程可以这样理解请求到达服务器 - 匹配路由 - 拉取页面数据 - 服务端渲染组件成 HTML - 返回完整 HTML - 浏览器展示 - 浏览器下载 JS - Hydration 绑定事件 - 后续进入客户端路由模式很多框架其实都按这个思路做Next.jsNuxt.jsRemix自建 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 风险。例如把用户输入直接插入模板scriptwindow.__DATA__ ${data}/script如果没转义可能被注入恶意脚本。所以 SSR 注水数据时一定要做安全转义。六、SSR 适合什么场景适合SEO 要求高的网站首屏体验要求高的页面内容展示型页面营销页、官网新闻、博客、电商详情页不一定适合后台管理系统强交互但 SEO 不重要的系统登录后内部系统因为后台系统通常SEO 不重要页面逻辑复杂SSR 带来的复杂度收益不高七、SSR、CSR、SSG 的区别1. CSR浏览器拿到空壳 HTMLJS 渲染页面。优点开发简单前后端分离自然缺点首屏慢SEO 差2. SSR每次请求时服务器动态渲染 HTML。优点首屏更快SEO 更好缺点服务端压力大实现复杂3. SSG构建时提前生成静态 HTML。优点性能最好SEO 好部署简单缺点不适合强实时动态内容八、面试回答模板你可以这样答1. 先说原理SSR 就是服务端渲染。浏览器请求页面时服务器会先根据当前路由获取数据再执行前端组件代码把页面渲染成完整 HTML 返回给浏览器。浏览器拿到 HTML 后可以直接展示首屏内容然后再下载客户端 JS 对已有 HTML 做 hydration绑定事件让页面具备交互能力。2. 再说解决的问题SSR 主要解决两个核心问题第一是首屏渲染慢CSR 需要等 JS 下载执行和接口返回后才能看到内容而 SSR 可以更快把可见内容返回给浏览器第二是 SEOSSR 返回的是完整 HTML更利于搜索引擎抓取页面内容。3. 最后说坑SSR 的常见坑包括服务端没有 window/document 等浏览器对象服务端渲染和客户端首次渲染不一致会导致 hydration 问题数据获取链路更复杂容易重复请求服务端渲染增加服务器压力缓存策略、样式收集、第三方库兼容、同构状态管理等都会比 CSR 更复杂。九、一句话总结SSR 的本质是“服务器先产出 HTML客户端再接管交互”它主要解决首屏性能和 SEO 问题但代价是同构开发、服务端压力和工程复杂度明显上升。

更多文章