9.2 服务端渲染 SSR:首屏的终极手段 本节摘要:SSR 把组件渲染成 HTML 字符串的工作搬到服务器,浏览器拿到首帧就是有内容的页面,再由客户端"水合"接管交互。本节讲清它的收益边界(首屏与 SEO)、水合的成本、与静态生成的区别,以及引入 SSR 带来的代码约束——这是一条有代价的终极路径,不是免费的午餐。 学完这节你能做什么 阅读完本节,你应当能够: 说出 SSR 解决的两类问题与不解决的问题; 描述从请求到可交互的 SSR 完整流程,解释水合是什么; 区分 SSR、静态生成 SSG、客户端渲染 CSR 的适用谱系; 列出引入 SSR 后必须遵守的代码约束。
本节摘要:SSR 把组件渲染成 HTML 字符串的工作搬到服务器,浏览器拿到首帧就是有内容的页面,再由客户端"水合"接管交互。本节讲清它的收益边界(首屏与 SEO)、水合的成本、与静态生成的区别,以及引入 SSR 带来的代码约束——这是一条有代价的终极路径,不是免费的午餐。
阅读完本节,你应当能够:
客户端渲染(CSR)的首屏路径很长:下载空壳 HTML → 下载脚本包 → 执行脚本 → 请求数据 → 渲染出内容。用户盯着白屏走完全程。SSR 把中间几步搬到服务器:请求到达时,服务器先取数据、把组件渲染成 HTML 字符串直接返回——首帧内容随第一个响应到达。
收益边界要划清。SSR 解决两件事:弱网与低配设备的首屏体验(脚本下载与执行被首帧并行化)、搜索引擎抓取(爬虫直接拿到内容完整的 HTML)。它不解决:交互卡顿(水合后还是那套客户端管线)、接口慢(数据还是要等,只是等待发生在服务器)、长列表性能。把 SSR 当万灵药的团队,多半会在水合账单上清醒。

服务器输出的 HTML 没有事件监听、没有状态,只是一张"照片"。脚本到位后,Vue 在浏览器里执行同一套组件代码,把虚拟树重建出来并与已有 DOM 匹配绑定——这个过程叫水合。用户视角:内容立刻可见,但水合完成前点按钮没反应,这段"看得见摸不着"的时间是 SSR 体验的固有暗礁。
水合的代码形态,服务器端与客户端各一个入口,保证两边跑同一份组件代码:
// 服务器端:渲染成字符串拼进页面 import { createSSRApp } from 'vue'; import { renderToString } from 'vue/server-renderer'; const app = createSSRApp(App); const html = await renderToString(app); // 客户端:同一应用,mount 时对已有DOM做水合而非重建 import { createSSRApp } from 'vue'; const app = createSSRApp(App); app.mount('#app'); // createSSRApp 的标志:根节点已有服务端输出
实际工程不会手写这些——Nuxt 这类元框架把服务器、路由、数据获取、水合全部封装好。读代码时要认得的标志是 createSSRApp:它告诉运行时"根节点可能已有服务端输出,挂载时做水合而不是重建"。
水合的隐患是前后不一致:服务器渲染时用的数据与客户端首次渲染时的数据不同(时间戳、随机数、接口两次结果不同),水合发现 DOM 对不上,轻则警告重则整树重建——首屏闪一下等于白干。纪律:组件里避免依赖本地时间与随机值做渲染分支,数据获取走框架的统一通道。
| 方案 | 首屏 | SEO | 服务器成本 | 适合 |
|---|---|---|---|---|
| CSR 客户端渲染 | 慢 | 弱 | 静态托管即可 | 后台管理、登录后应用 |
| SSR 服务端渲染 | 快 | 好 | 每请求都渲染,高 | 内容随用户变化的toC页面 |
| SSG 静态生成 | 最快 | 好 | 构建时出页,低 | 文档站、营销页、博客 |
| 混合(部分预渲染加部分SSR) | 按页 | 按页 | 中 | 大型站点差异化策略 |
选型判断两问:内容是否依赖每个请求的上下文(登录身份、实时数据)?需要 SEO 吗?纯后台系统两问皆否,CSR 足矣;电商详情页两问皆是,SSR;文档博客内容固定,构建期全静态化成 SSG,连服务器渲染都省了。Nuxt 对三种模式都提供一等支持,切换策略不换框架。
SSR 不是加个配置的事,它改变了运行环境假设,一批代码要跟着守规矩:
浏览器内的优化讲完了,下一章进入 Vue 3:框架把许多优化做进了编译器与响应式内核。