美文网首页Vue
vue 服务端渲染(一):初探

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

作者: 梦想成真213 | 来源:发表于2020-09-30 16:43 被阅读0次

    概念

    • 客户端渲染:在浏览器端进行渲染,服务端返回的只是 <div id="app"></div> 的空标签文档;
    • 服务端渲染:在服务器就做好数据的的拼接,请求返回的 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: `<div>我是:{{name}},{{age}}岁</div>`
    })
    
    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 的标记

    <!--vue-ssr-outlet-->
    
    // index.html
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>vue ssr template</title>
    </head>
    <body>
      <!--vue-ssr-outlet-->
    </body>
    </html>
    

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

    const Vue = require('vue')
    const VueServerRenderer = require('vue-server-renderer')
    
    const vm = new Vue({
      data() {
        return {
          name: '小可爱',
          age: 3
        }
      },
      template: `<div>我是:{{name}},{{age}}岁</div>`
    })
    
    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中加入这个<!--vue-ssr-outlet-->标签表示渲染到这个位置上
    }) // 创建一个渲染器
    
    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
      // // <div data-server-rendered="true">我是:hcj,20岁</div>
    })
    
    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 服务端渲染(一):初探

        本文链接:https://www.haomeiwen.com/subject/oeebyktx.html