Vue 服务端渲染入门介绍

842 阅读4分钟

为什么需要服务端渲染(SSR)

更好的 SEO

搜索引擎爬虫可以抓取到静态 HTML 以及同步Javascript 生成的页面,但是搜索引擎"可能不会等待" (Google 和 Bing 已经支持单页应用和AJAX,据说连百度对中文单页应用的支持也不错)AJAX 等异步 Javascript 执行完成再抓取页面。

如果使用服务端渲染,搜索引擎可以更容易抓取到这些页面。 需要注意的是,并不是必须使用服务端渲染才能达到良好的 SEO,以下介绍另外两种解决方案。

预渲染 (Prerendering)

为了改善少数静态页面的 SEO(例如主页,关于页面,联系方式),使用预渲染的方式即可。在构建前端代码时(Building Time)针对特定的路由直接生成静态 HTML。

无头浏览器(Headless Browser)

在客户端请求时(Requesting Time)检测 User Agent ,如果发现是爬虫;则使用无头浏览器来渲染 SPA 应用返回静态 HTML,如果是普通用户,则照常返回 SPA 应用代码。相比于前后端同构代码来做服务端渲染,这种方案更加轻量,适合 QPS 较小的服务。

更好的首屏性能

由于页面是在服务器上渲染返回的,客户端无需下载 Javascript 并运行,用户会更快地看到完整渲染的页面,对于那些网络带宽较小和性能较差的设备来说提升尤其明显。对于看重TTI (TTI ,time to interactive,指用户从第一个请求发出,到能够与页面交互,这之间的时间差;决定用户的跳出率、转换率、时间)的服务,使用服务端渲染是优化性能的一种方案。

性能的重要性:

developers.google.com/web/fundame…

服务端程序

非 Node.js 环境中使用

Vue 官方提供的 vue-server-renderer 只能在 Node.js 环境中使用,虽然在非 Node.js 的环境运行可以通过移植 vue-server-renderer/basic.js 实现,但是业界生产环境普遍是使用 Node.js:在 Github 上

搜索 vue v8jsvue nashronssr ashronssr v8js 能找到的仓库屈指可数(加入 react 关键词,搜索得到的结果稍微多一些,大概有几十个。)

业界使用 Node.js 有以下几个原因:

  • Node.js 的生态完善且成熟,除了服务端渲染,还可以做日志、监控、认证等功能。
  • 大多前端工程师的后端技术栈主要是 Node.js。
  • JS 引擎的兼容性和性能问题。

知乎上的讨论:

www.zhihu.com/question/54…

实现

Vue SSR 时间线

  1. 客户端(浏览器)请求服务端
  2. 服务端数据预取(Server Data Fetching)
  3. 服务端渲染页面的 HTML,将预取的数据序列化为 window.__INITIAL_STATE__,并注入 HTML。
  4. 服务端返回渲染出的 HTML 以及客户端代码
  5. 客户端激活服务端返回的 HTML (client-side hydration)
  6. 客户端使用 store.replaceState(window.__INITIAL_STATE__)注入服务端预取的数据
  7. 如果预取数据不存在,则客户端可能需要获取数据。

vue-server-renderer

官方 Guide + Demo:

ssr.vuejs.org/zh/

github.com/vuejs/vue-h…

第三方 Demo:

zhuanlan.zhihu.com/p/64829195

使用了 Vue v2.6.0+ 官方提供的 serverPrefetch API。

官方中文 Guide 中没介绍这个 API,自行实现了静态方法来做服务端数据预取。

nuxt.js

基于 vue-server-renderer 的应用框架,提供了 Vue.js 开发服务端渲染的应用所需要的配置和 API。

推荐先学习 vue-server-renderer 的教程和 API,了解 Vue 服务端渲染的基础知识,再去使用 nuxt。

其它

构建配置和服务端热重载

相比于单页应用工程所需的 Webpack 配置,服务端渲染的工程要复杂一些

ssr.vuejs.org/zh/guide/bu…

ssr.vuejs.org/zh/guide/bu…

缓存和优化

每次请求服务端是都会重新渲染页面和组件,可以做页面缓存和路由缓存

ssr.vuejs.org/zh/guide/ca…

互切和降级容错

服务端不可用时,如何降级为普通的单页应用

zhuanlan.zhihu.com/p/60816418

外部扩展库的兼容性

例如微信 JSSDK 无法在 Node.js 环境中运行,在服务端渲染时,要做兼容性检查。

日志监控系统

服务端接收到的请求信息、出现的异常信息需要记录,服务端健康情况需要及时反馈。

zhuanlan.zhihu.com/p/69109307

zhuanlan.zhihu.com/p/71705547