vue 服务端渲染(一):初探

概念

  • 客户端渲染:在浏览器端进行渲染,服务端返回的只是
    的空标签文档;
  • 服务端渲染:在服务器就做好数据的的拼接,请求返回的 html 是完整的文档。

客户端渲染,服务端渲染对比

  • 客户端渲染不利于 SEO 搜索引擎优化(返回的是空标签);
  • 服务端渲染出来的文档可以被爬虫抓取,客户端异步渲染很难被爬虫抓取;
  • 服务端渲染直接将 HTML 字符串传递给浏览器,大大加快了首屏加载时间;
  • 服务端渲染占用更多的 CPU 和内存资源;
  • 在服务端渲染模式下,一些常用的浏览器 API 可能无法正常使用(服务端没有 document,window);
  • 服务端渲染只支持 vue 中 beforeCreate 和 created 两个生命周期(因为没有 dom,所以不涉及 mounted 等)

SSR 运行过程:

  • 服务端渲染只是做首屏的渲染;
  • 后续在浏览器中的路由切换逻辑执行的是客户端渲染(前端路由切换页面,每个路由返回的首屏是服务端来做)
  • 服务端渲染使用 Node 服务来实现(前后端分离模式)
  • 传统的服务端渲染是 jsp asp php+smarty,不适合前后端分离开发模式

整个打包过程

  • 首先要保证客户端渲染模式下可以跑起来,然后提供一个服务端入口
  • 通过将一份代码打包出来两份逻辑(客户端和服务端)
  • 前端拿到打包出来的 bandle.js,后端通过打包的结果渲染出字符串返回给浏览器
  • 浏览器展示 = 前端 bundle.js + 服务端渲染的字符串
    如下图:展示了打包过程:


安装包

  • vue vue-server-renderer(通过vue-server-renderer来实现vue的服务端渲染)
  • koa koa-router(通过 node 来做服务端)
npm install vue vue-server-renderer koa @koa/router -D

开发中

本地新建一个文件夹 vue-ssr-demo,初始化项目npm init -f,生成一个package.json,npm install安装需要用到的包,新建一个server.js来启动服务:

// server.js
  const Vue = require('vue')
const VueServerRenderer = require('vue-server-renderer')

const vm = new Vue({
  data() {
    return {
      name: '小可爱',
      age: 3
    }
  },
  template: `
我是:{{name}},{{age}}岁
` }) const Koa = require('koa') const Router = require('@koa/router') // 创建一个渲染器 const render = VueServerRenderer.createRenderer()// 创建一个渲染器 let app = new Koa() // app实例 let router = new Router() // 路由实例 router.get('/', async (ctx) => { ctx.body = await render.renderToString(vm) // render.renderToString 返回的是一个promise }) app.use(router.routes()) app.listen(3500)

启动命令:nodemon server.js,VueServerRenderer.createRenderer()创建一个渲染器,调用渲染器 renderToString 方法 传入vm实例,访问http://localhost:3500/ 可以看到页面展示:


页面上显示了data-server-rendered="true"表示服务端渲染。

通常我们都是有一个 html 模板,然后将打包的内容放进去,新建一个 html 文件,写下vue server 的标记


// index.html



  
  
  vue ssr template


  


server.js 中读取本地的index.html文件,文件内容作为渲染器模板即可:

const Vue = require('vue')
const VueServerRenderer = require('vue-server-renderer')

const vm = new Vue({
  data() {
    return {
      name: '小可爱',
      age: 3
    }
  },
  template: `
我是:{{name}},{{age}}岁
` }) const Koa = require('koa') const Router = require('@koa/router') const fs = require('fs') const path = require('path') const htmlStr = fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf8') // 同步读取文件 // 创建一个渲染器 const render = VueServerRenderer.createRenderer({ // 可以从本地读取html文件当作模板 template: htmlStr, // 采用哪个模版去渲染,在html中加入这个标签表示渲染到这个位置上 }) // 创建一个渲染器 let app = new Koa() // app实例 let router = new Router() // 路由实例 router.get('/', async (ctx) => { // ctx.body = 'hello world' ctx.body = await render.renderToString(vm) // render.renderToString 返回的是一个promise // //
我是:hcj,20岁
}) app.use(router.routes()) app.listen(3500)

监听文件改动,自动重启服务

npm install nodemon -g

目前实现了一个最简单的 ssr,后续文章加入客户端配置,服务端配置,vue-router, vuex 来实现完整的 ssr。

github:https://github.com/mxcz213/vue-ssr-demo/tree/part-one

你可能感兴趣的:(vue 服务端渲染(一):初探)