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.缓存过程
5.结合缓存,修改配置文件。
vue打完包后会生成dist文件,部署到服务器上之后,每次客户端请求都会命中缓存,导致文件更新不成功,所以我们需要在更新迭代后让服务器返回最新的内容。
我们在vue.config.js中修改每次打包后的文件名,每次生成文件名带有时间戳,
所以部署后都会重新请求服务器拉取最新的文件。
更改ngnix文件
在配置完vue.config.js后,你会发现还是不生效,是因为index.html文件也会存在缓存。
所以我们可以设置ngnix,来将html文件不缓存。
也可以使用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文件。这样可以及时获取更新的内容了