别用ctrl+F5,ctrl+shift+delete清缓存了,VUE部署就生效

1,790 阅读3分钟

1.问题

项目部署完成后,刷新页面并未生效,需清除缓存,才可重新请求服务器,拉取最新的资源。大部分用户可是不知道缓存概念的,让其手动清缓存更是扯。

2.要求

所以达到的效果就是,每次迭代完成后,用户无需清除缓存来获取最新的资源。

3.思考

1.不使用缓存,从源头上禁止掉。(简单,直接在index.html中设置禁用缓存,但是用户在每次加载都需要重新拉取资源,造成流量的损耗,也影响页面的加载速度和体验感。)

    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-Control" content="no-cache">
    <meta http-equiv="Expires" content="0">`

2.无更新,使用现缓存,有资源更新的时候,更新缓存,

这种是最佳的实践,但是需要搞明白强缓存,协商缓存

4.缓存

1.强缓存

强缓存是当我们访问URL的时候,不会向服务器发送请求,直接从缓存中读取资源

Expires
    缓存过期时间,用来指定资源到期的时间,有一个缺点是根据本地时间来判断是否过期,一旦本地时间被篡改就会造成失效。
Cache-control
    max-age : 设置过期时间
    s-maxage:设定代理服务器缓存时间
    private:内容只缓存到私有缓存中,只有客户端可缓存,服务器不可缓存
    public:所有内容都可被缓存
    no-store:不缓存任何内容
    no-cache:每次请求服务器获取最新内容,如果没有新内容,就使用缓存。
    
Cache-control优先级高于Expires

2.协商缓存

也叫对比缓存,是携带两个字段(Last-Modified、Etag)来请求服务器来确定资源是否可用。

Last-Modified
    配合if-modified-since,是请求数据带上的,值是上次浏览器返回的Last-modified
ETag
    配合 if-none-match,是浏览器请求数据时带上的字段,值是上次服务器返回的`ETag`

ETag优先级高于Last-Modified

3.缓存优先级

强缓存和协商缓存如果同时存在时,会去先对比强缓存是否还在有效期。
如果强缓存还在有效期内则直接使用强缓存,否则协商缓存生效,即`强缓存 > 协商缓存`

4.缓存过程

image.png

5.结合缓存,修改配置文件。

vue打完包后会生成dist文件,部署到服务器上之后,每次客户端请求都会命中缓存,导致文件更新不成功,所以我们需要在更新迭代后让服务器返回最新的内容。

   我们在vue.config.js中修改每次打包后的文件名,每次生成文件名带有时间戳,
   所以部署后都会重新请求服务器拉取最新的文件。

image.png

更改ngnix文件

在配置完vue.config.js后,你会发现还是不生效,是因为index.html文件也会存在缓存。
所以我们可以设置ngnix,来将html文件不缓存。

image.png

也可以使用meta标签来设置

    <meta http-equiv="Pragma" content="no-cache">
    <meta http-equiv="Cache-Control" content="no-cache">
    <meta http-equiv="Expires" content="0">`

基本上设置完成之后,就可以部署后不清缓存生效了。

6.优化

实现是实现了但是发现一个问题就是,每次部署后刷新会出现几秒的白屏,用户体验不是很好。
解决
    1.在每次打包的时候写入一个ver_record.json文件,里面记录一个当前打包时间,配置在vue.config.js文件       
function getLocalTime(nS) {
  var d = new Date(parseInt(nS));
  var date = (d.getFullYear()) + "-" +
    (d.getMonth() + 1) + "-" +
    (d.getDate()) + " " +
    (d.getHours()) + ":" +
    (d.getMinutes()) + ":" +
    (d.getSeconds());
  return date;
}
const fs = require('fs')
const versionJSON = {
  "compileTime": getLocalTime(new Date().getTime())
}

fs.writeFile("public/ver_record.json", JSON.stringify(versionJSON), (err) => {
  console.log('文件写入成功' + versionJSON)
})
    2.在main.js中加入判断
// 检测当前版本是否最新,如compileTime不同,自动更新
const compileTime = require('../public/ver_record.json').compileTime
const oldCompileTime = window.localStorage.getItem('compileTime')
console.log(oldCompileTime, compileTime, '11111ccccc')
if (compileTime !== oldCompileTime) {
  window.localStorage.setItem('compileTime', compileTime)
  location.reload()
}

可以增加一个定时器,每隔三分钟获取一下ver_record.json文件。这样可以及时获取更新的内容了