VueSSR高阶指南

嗨 各位小伙伴好,很久没有写文章了,此次分享一下咱们从使用node以来,前端架构上的一些优化 若是看过我上一篇文章B站的前端之路的小伙伴可能知道 咱们从去年开始打烊 使用node 到如今已经经历了一年的迭代,承载的访问量也从百万级别 扩大到了如今的亿级别,此次补充一些干货吧~css

vue如何实现热更新

咱们都知道,对于node来讲,前端vue代码的迭代节奏是很快的,可能一周要迭代几回,可是node的迭代却没那么平凡,可能一周更新一次甚至更久,那么为了node服务的稳定,减小node服务的发布次数,是很是有用的。 配置中心是确定须要的,由于须要经过配置不一样的资源版本号,来通知node服务更新服务上的版本号 那么 咱们的vue代码 要如何改造才能实现热更新呢? 咱们就以vue官方给的例子来看
如下代码是我截取的两段代码官方案例:
首先他定义了一个createRenderer的方法
里面调用的是vue-ssr的createBundleRender方法来建立的渲染函数
html

而后传入了使用了三个文件,template.html bundle.json 和clientmanifest.json
这里能够看到 在createRender的时候 传入的clientMainfest bundle 都是reqire的 那么有同窗会想,我要支持热更新 是否是根据require的缓存机制,去定时的清理缓存?虽然也能实现可是其实不用的 我查询了官方的api文档,其实bundle支持三种参数
而后再看下vue的源码,若是传入的是一个绝对路径,相似于上面这个案例 require某个dist目录下的bundle.json文件的时候 作了什么处理
它判断 若是是一个js 或者json文件路径的 那么 他会先读取这个文件,而后经过json转化一下成对象,而后再走下面的判断是不是oject逻辑 那么,咱们不是能够替他作这个事情嘛 咱们能够从远程读取到bundle文件 而后将他转化成bundle 而后传入给createBundleRender方法 就能够不用经过require方法去获取了 而后远程bundle文件加上版本号,就能够实现经过配置来热更新

vue项目与node项目分离

为了先后端分离,咱们在前端和api层中间,架构了一层node层,用来作服务端渲染,来加快用户的首屏可用和对搜索引擎的友好。项目一开始放置在同一个git仓库里面,分别放在client目录和server目录中(或者相似于vue 官方例子中的同样,node服务可能只有一个sever.js。由于server中可能须要client中的一些资源,因此不得不将他们放在一块儿。后来经过配置中心驱动以后,client 和server 能够彻底独立,经过配置中心创建链接。因此彻底能够将client项目和server项目分离开。 前端

其实就是在前端项目中,再作了一次先后端分离,此次分离的缘由 跟与api的先后端分离有些不同。此次是由于 第一个 前端vue项目本就是一个彻底独立的项目,拖着server项目反而显的不是那么灵活,一样,server里面包含了client,虽然能够独立发布,可是由于迭代周期的不一样,在管理分支上面总归有点变扭,索性分开,各过各的 各过各的是极好的,但是开发的时候怎么各过各的啊(f***~),我开发的时候要走服务端渲染的逻辑的啊,你让我先基于客户端开发,而后再配合着node调试一波?那可不是反而增长了开发成本 有没有可让client独立也能跑ssr的逻辑,而后最后只要跟正式的node服务经过配置中心配合起来就行了呢? 有啊,给client配置一个简单的服务不就行了么?通常的nodessr不都是这样的么 说白了就我上面说的,一个sever.js。里面是一个基于koa的简单服务,加上了koawepack的中间件 (koa-webpack),用来作开发时候的热加载。 而后经过不一样的启动脚本,来配置上不一样的环境变量参数,以此来启动不一样的页面开发,这样子,开发就方便多了,npm run start:home 就是开发首页,npm run start:video 就是开发播放页 后面加上server参数就是开发服务端渲染 例如 npm run start:home:server (这里我只提供一个思路昂~具体实现要讲的东西太多了,这里不太想写 >_>~~)

容灾

既然是个node服务,那么对于服务也要有相应的容灾方案,否则怎么放心将大流量交给它 那么,咱们须要一个降级方案以备不时之需(如下内容须要创建在你对vuessr有必定了解的基础之上) 首先 vue 服务端渲染都有两个入口文件,entryclient.js和entryserver.js 若是要支持降级,那么须要在entryclient.js上面动一些手脚,咱们仍然以官方例子为例 如今index.temlate.html 增长一个客户端渲染容器,一个名为de-app的div(<!--vue-ssr-outlet-->是服务端渲染的占位符) vue

而后,咱们看一下entryclient.js里面
这里是用来同步服务端数据到客户端store里面的,那么,若是降级到客户端渲染,这里就须要作一下兼容
咱们默认服务端渲染必定会有window.__INITIAL_STATE__,若是没有 说明服务端没有帮咱们取到数据,也就是降级到了客户端渲染,那么须要从新运行如下asyncData方法来从客户端获取一下数据,而后挂载到咱们预先设定好的de-app上面,固然 本来挂载到app上的 也要作一下判断了
这样子,服务端若是没有渲染出内容来,那么,页面仍是能够经过客户端渲染,从新走一遍逻辑,正常输出页面来。 vue代码改完了,咱们在构建的时候,也要以两种目的去打包咱们的html,一种是纯粹的模版html(template.html),里面除了一些固定的js引入外,没有vue打包相关的js引入,是用来给服务端渲染看成模版用的(就是上面说的传递给createBundleRender的),另外一个打包将构建好的js css引入进去了(degrage.html),能够直接当客户端渲染的静态模版使用 (就是使用两次htmlwebpackplugin 一个传chunks 一个不传)
那么具体怎么使用这两个文件呢? 咱们准备了三层降级

  • 1.首先 node服务上面,本身起了一个服务,用来监测全部的node进程的cpu使用率是否大于设定的阈值,若是超过设定阈值,那么返回咱们事先准备好的degrade.html文件,降级掉服务端渲染,能够大大减小服务端的渲染压力,固然也能够手动设置是否须要降级嘛,来去自如
  • 2.若是Node不幸 炸了,那么 须要在slb 这一层上 也就是nginx 作一个配置,若是服务返回的code是5xx,那么将流量指向咱们实现发布好的degrade.html
  • 3.若是很是不幸,全炸了,那么若是页面配置了cdn缓存,cdn回源失败,就返回以前缓存上的页面
    那么在极端状况下,其实仍是会有首屏页面展现给用户的(数据兜底会让这个方案更完美,下次有机会再补上吧)
    此次就这么多吧,下次可能会补充上一些别的优化和react的一些黑科技~

哔哩哔哩 干杯~

相关文章
相关标签/搜索