vue中的ssr和前后端同步渲染


1 ssr

全称:server side render(服务器端渲染),可以在服务器端渲染应用程序。

前端渲染问题:

1 白屏时间长,影响用户体验。

2 不利于搜索引擎优化( SEO )

所以要在服务器端渲染应用程序

1.1 服务器端渲染:

 vue为服务器端渲染提供了模块: vue-server-renderer,如没有请先下载:npm install vue-server-renderer

  该模块提供了createRenderer方法,来创建渲染器

   渲染器提供了renderToString方法,渲染应用程序组件

   渲染器实现了promise规范,因此:可以通过then方法监听成功,可以通过catch方法监听失败

1.2 服务器端渲染模板

想在模板中渲染应用程序分成两步:

  第一步:在createRenderer方法中,通过template引入模板文件

  第二步:在模板文件中,通过定义应用程序渲染的位置。

      注意:在webpack4.x版本中,默认压缩删除注释,这将导致服务器端渲染模板不能用,

      解决办法:在html-webpack-plugin插件中的readme.md中,(365行)将代码复制到前端编译文件中

          (webpack.client.js),在plugins下,通过minify配置,将removeComments:true改为false

例如:创建一个vue应用程序:

 在后端去引入vue应用程序,将模板内容渲染到页面上:

在index.html文件中,通过定义应用程序渲染的位置:

浏览器端渲染:

  1 白屏时间长,影响用户体验,

  2 不利于SEO优化

服务器端渲染:

  无法绑定交互

为了解决浏览器端与服务器端渲染的问题,则要使用前后端同步渲染技术。

2 前后端渲染环境

前端渲染

是为了给用户使用,因此希望资源加载的快(压缩,打包,添加指纹等等)

  为了更好的效果,要加载样式;为了看到页面,要处理模板等...

但是服务器端渲染不需要考虑这些问题,只需要一个应用程序组件,并最终将其渲染成字符串。

因此前后端渲染有不同的入口文件,有不同的webpack配置

有不同的入口文件

  前端入口文件,要让应用程序组件上树;

  后端入口文件,只需要一个应用程序组件

不同的webpack配置

前端要考虑样式,模板,性能优化(压缩,打包,添加指纹等)等

后端只要将ES Module规范,编译成CommonJS规范即可。

2.1 目录部署

  模拟vue-cli的目录部署:

  config 存储配置文件

  home 前端开发的项目

    public 存放开发时模板文件

    src 开发目录

  views 模板发布的目录

  static 静态资源发布的目录

  app.js 服务器入口文件

3 npm 指令

由于webpack配置存储到特定位置,因此启动webpack指令很长

  webpack --config 文件位置

为了简化webpack的运行,则可以配置一些npm指令,像vue cli一样运行:

  npm run client 运行前端配置

  npm run server 运行服务器端配置

  npm run start 同时运行前后端配置

  npm run start:client 监听并运行前端配置

  npm run start:server 监听并运行后端配置

要在package.json中,配置scripts项,来定义指令

4 服务器端渲染

  1 不需要模板,不用写html插件

  2 不需要样式,不用写style-laoder,不需要拆分样式

  3 不需要性能优化、拆分模块,添加指纹,服务器端本地引入文件,因此打包在一起就可以了等

  4 通过target: node配置,说明给node使用。

  5 在output.libraryTarget: commonjs2, 将ES Module规范转成commonjs规范

  6 使用vue-server-renderer插件,发布json文件(先引入vue-server-renderer和这个插件下的server-plugin文件)

    在参数对象中,通过filename属性,可以自定义json文件的发布位置。

为了使用发布的json文件,vue-server-renderer提供了createBundleRenderer方法

  第一个参数表示json文件

  第二个参数表示配置对象

    template定义模板文件的位置

插值语法:vue服务器端渲染允许在渲染页面的时候,向页面中,插入一些数据。

  在renderToString方法中传递数据。

  在模板中,通过插值语法插入数据

    {{}} 渲染文本插值

    {{{}}} 渲染标签插值

    例如之前简单的做SEO搜索引擎优化:

    可以在html文件中,添加字段  

                     插值语法可以简化书写:   在renderToString方法中传递这些数据:   

  在html文件中使用插值语法渲染:

5 路由同步

路由同步就是说:前后端渲染的页面是一致的。

如果使用hash路由,改变hash,不会向服务器端发送请求,因此服务器端不会更新页面,并且服务器端无法获取hash数据,无法解析hash数据。

所以在前后端同步渲染的时候,只能使用history路由测试(多页面应用程序)。

当使用history策略的时候,不同页面应该请求同一个路径下的静态文件,所以静态文件的路径应该是绝对路径

注意:使用history策略,服务器端要做重定向

5.1 前后端解析

前端解析:

 前端有路由模块,是专门用来解析前端路由的。

解析路由:

可以使用路由模块解析路由,路由实例化对象提供了一些方法

  push 将一个新的地址加入到路由序列中。

  onReady 监听路由解析完毕

  getMatchedComponents 当前路由规则下,匹配的组件。

后端解析:

 后端要在渲染页面的时候解析,所以要通过请求对象获取url地址

 再将url地址提交给vue-router模块创建的路由实例化对象去解析。

为了将url信息传递给后端入口文件,分成两步:

  第一步:在renderToString方法中,传递数据

  第二步:将后端入口文件改成一个返回promise对象的方法

      方法的参数就是renderToString方法传递的数据

      在方法中,解析路由,并最终使用promise对象的resovle或者reject方法,返回处理结果。

6 同步数据

同步数据就是与页面一起返回的数据。

由于是与页面一起返回的,因此可以在页面中直接使用这些数据,不必发送请求了。

一些重要的,需要首屏渲染的内容,可以放在同步数据中。

自己实现的代码:点我