服务端渲染(SSR)

一、重构背景与目标

1. 业务场景

官网宣传页、商城、资讯等核心模块需重构,此类场景对SEO、首屏加载速度要求较高。

2. 技术栈对比

阶段 技术框架 核心痛点
旧版 Express + Ejs 开发效率低、前端交互体验差
重构后 Vue + Nuxt.js / Vue + Quasar 兼顾SSR、开发效率、跨端能力

3. 核心重构目标

  • 保留并强化SEO能力(核心诉求);
  • 优化页面加载速度(提升首屏内容到达时间);
  • 基于Vue生态提升开发效率;
  • 兼顾后续扩展(如跨端部署)。

二、服务端渲染(SSR)核心认知

SSR(Server-Side Rendering)指将Vue/React等前端应用的组件在服务器端渲染为HTML字符串,再发送到浏览器,浏览器接管后转为可交互的SPA。与传统SPA相比,核心价值与权衡如下:

1. SSR核心优势

  • 更优的SEO:搜索引擎爬虫可直接抓取完整渲染的HTML(SPA异步加载内容易被爬虫忽略,同步SPA虽可索引,但异步内容仍存在问题);
  • 更快的首屏加载:无需等待所有JS下载/执行,用户能快速看到完整内容,尤其适配弱网/低配设备,提升转化率;
  • 更好的用户体验:首屏无加载菊花图,内容直达。

2. SSR权衡点(需重点考量)

  • 开发限制:浏览器专属API(window/document)仅能在mounted等生命周期使用,第三方库需适配SSR;
  • 部署复杂度:需Node.js运行环境,无法直接部署在静态文件服务器(如Nginx纯静态);
  • 服务器负载:Node.js渲染完整应用属于CPU密集型操作,高流量场景需搭配缓存策略(如页面缓存、CDN)。

3. 选型判断

仅当「首屏加载速度/SEO」是核心指标时(如官网、商城、资讯站),才建议使用SSR;内部系统、低流量工具类应用无需SSR。

三、重构核心框架实战

1. Vue + Nuxt.js:专注Vue SSR的一站式框架

核心定位

Nuxt.js是基于Vue的服务端渲染框架,内置路由、打包、SSR等能力,无需手动配置Vue SSR底层逻辑,是Vue生态中SSR的首选方案。

重构使用心得

  • 开发效率高
    • 约定式路由(pages目录自动生成路由),无需手动配置vue-router
    • 内置asyncData/fetch钩子,支持在服务器端获取数据(解决SSR数据预渲染问题);
    • 集成Webpack/Vite、ESLint、PostCSS等,开箱即用。
  • SEO友好
    • 自动生成head标签(标题、关键词、描述),支持自定义每个页面的SEO配置;
    • 服务端预渲染所有异步数据,爬虫可直接抓取完整内容。
  • 部署灵活
    • 支持nuxt generate生成静态站点(SSG),兼顾SSR与静态部署;
    • 支持Node.js服务部署、Serverless部署(如阿里云FC)。

核心使用流程(极简)

1
2
3
4
5
6
7
8
# 1. 创建项目
npx create-nuxt-app nuxt-ssr-demo
# 2. 开发环境(SSR模式)
npm run dev
# 3. 构建生产环境
npm run build
# 4. 启动服务
npm run start

2. Vue + Quasar:跨端+SSR一体化方案

核心定位

Quasar是Vue生态的跨平台框架,支持将同一套代码打包为SSR、SPA、PWA、桌面端(Electron)、移动端(Capacitor)等,SSR仅为其多端能力之一。

重构使用心得

  • 跨端优势突出:重构后若需扩展移动端/桌面端,无需额外开发,仅需调整打包命令;
  • SSR配置简洁
    1
    2
    3
    4
    # 开发SSR
    quasar dev -m ssr
    # 构建SSR
    quasar build -m ssr
  • 与Nuxt的对比
    • 优势:跨端能力强,组件库丰富(无需额外引入UI库),适合需多端部署的场景;
    • 劣势:SSR相关生态(如SEO优化、数据预渲染)不如Nuxt专注,需手动配置部分细节。

适用场景

重构中「商城模块」需兼顾移动端适配,选择Quasar实现SSR+移动端快速适配,减少多端开发成本。

3. 框架选型总结

场景 推荐框架 核心原因
纯Vue SSR、SEO优先 Nuxt.js 专注SSR,SEO/路由/数据预渲染更完善
跨端部署(SSR+移动端/桌面端) Quasar 一套代码多端部署,组件库丰富

四、SSR填坑指南(实战踩坑)

1. 核心报错:connect ECONNREFUSED 127.0.0.1:80

问题原因

Axios的baseURL未指定协议(如api.yhorz.cn/api),客户端请求时浏览器会自动补全当前页面协议(http/https),但服务器端无浏览器环境,无法补全协议,导致请求失败。

解决方案

baseURL必须显式指定协议:

1
2
3
4
5
6
// 错误写法
axios.defaults.baseURL = 'api.yhorz.cn/api';
// 正确写法
axios.defaults.baseURL = process.env.NODE_ENV === 'production'
? 'https://api.yhorz.cn/api'
: 'http://localhost:3000/api';

2. 其他常见坑及解决方案

  • 浏览器API报错(window is not defined)
    • 方案1:将浏览器API调用放在mounted生命周期(仅客户端执行);
    • 方案2:通过process.client判断环境(Quasar/Nuxt内置该变量):
      1
      2
      3
      4
      if (process.client) {
      // 仅客户端执行的代码(如操作localStorage、DOM)
      window.scrollTo(0, 0);
      }
  • 样式渲染异常
    • 原因:服务器端渲染时样式未正确注入;
    • 方案:使用scoped样式,或确保样式文件在服务器端被正确打包(Nuxt/Quasar默认处理,自定义样式需避免@import异步加载);
  • 数据预渲染重复请求
    • 原因:asyncData(Nuxt)/服务器端数据请求在客户端再次执行;
    • 方案:通过状态管理(Pinia/Vuex)缓存数据,避免重复请求。

五、相关资料

总结

关键点回顾

  1. SSR核心价值是提升SEO和首屏加载速度,仅适用于官网、商城、资讯等对外核心站点;
  2. Vue SSR重构优先选择Nuxt.js(专注SSR),需跨端部署则选Quasar;
  3. SSR开发需重点规避「浏览器API在服务端执行」「Axios协议缺失」等问题;
  4. 部署SSR需搭配Node.js环境,高流量场景需增加缓存/CDN降低服务器负载。

本次重构通过Nuxt.js/Quasar实现了SSR落地,既保留了SEO能力,又提升了开发效率和页面加载速度,同时Quasar为后续跨端扩展预留了空间,符合业务核心诉求。


服务端渲染(SSR)
https://cszy.top/20210308-服务端渲染/
作者
csorz
发布于
2021年3月8日
许可协议