1

背景

在开发的过程中,很多时候会遇到发布的代码没有在浏览器上及时生效,场景:

测试:快来看,你这个bug没有改对
开发:是不是哦,强制刷新一下浏览器试试呢
测试:哦,对了...

但真实的用户怎么办?

基础知识

浏览器缓存位置

1.Service Worker (离线网页,PWA的核心技术)

839C7158-4709-4986-9C7D-3E77FEAE43A9.png

2.Memory Cache(内存中的缓存)

33183F9F-5922-4B9D-92DB-8D2E2CE428CA.png

3.Disk Cache(硬盘中的缓存)

5E039573-1AF6-4277-AC72-56733F06B75C.png

4.Push Cache(推送缓存)

备注:2,3非常常见,1稍微要复杂一点,一些知名网站正在使用,如:淘宝,4没用过

浏览器缓存策略

1.强缓存:不会向服务器发送请求,直接从缓存中读取资源,会有如下状态:
839C7158-4709-4986-9C7D-3E77FEAE43A9.png
33183F9F-5922-4B9D-92DB-8D2E2CE428CA.png
5E039573-1AF6-4277-AC72-56733F06B75C.png

2.协商缓存:强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存,会有如下状态:
BBC996EE-C748-488A-B35F-6DAE17EEC06C.png
158514EC-95C4-479F-843E-54C690245C9B.png

备注:304表示虽然经历了服务器这一步,但该资源没有更新,于是继续使用缓存

解决方案

一、 文件名加hash值(最常见的方式)
如果你是用的现成的脚手架,如:vue-cli, create-react-app等,别人已经帮你做好了,基本不能遇到缓存的问题

二、文件名加不了hash值
在实际的项目开发中,就算我们是基于市面上流行的脚手架开发,也会遇到有一些js文件需要在index.html中直接用script标签引入,比如:config.js,里面写一些前端的配置,比如要访问的后台的服务地址等,方便运维部署的时候灵活设置,这样的文件就不方便加hash值了

对于这类文件往往有两种解决方式:

1.文件名加版本号,如:config-1.0.0.js,config-2.0.0.js,可参考jQuery
优点:可以对这类不常变的文件,设置长时间缓存,文件改变之后,升级版本号,这样既提高资源加载速度又能及时更新
缺点:文件名改变,index.html里面的引入也需要对应改变,对外提供的配置文件名不是固定的

2.nginx中配置,如

    lcation /config.js { 
        add_header Cache-Control no-cache; 
    }

特定文件每次都向服务器请求,走协商缓存,注意:no-cache 是走协商缓存,no-store 才是不适用任何缓存
优点:对外提供的配置文件名统一
缺点:每次都会向后台请求,由后台判断是否使用缓存,速度肯定要比直接取本地的慢,但影响不大
注意:IE浏览器是一个奇葩的存在,以上方法不会作用于IE浏览器icon的更新,强制刷新也无效,只能用更换名字或者加版本号,如:
<link rel="icon" href="home2.png">
<link rel="icon" href="home.png?v=2">

个人建议:
如果你的文件很稳定,比如几个月,半年才修改一次,建议采用第1种
如果你的文件并不稳定,修改的频率很高,建议采用第2种

注意点

很多人可能会遇到这样的问题,既没有在客户端的请求中控制缓存,也没有在服务器的返回中控制,为什么浏览器还是会有缓存?

对于这类情况,浏览器默认会采用一个启发式的算法, 通常会取响应头的Date - Last-Modified值的10%作为缓存时间

Date 原始服务器消息发出的时间
Last-Modified 请求资源的最后修改时间

怎么理解呢,拿config.js来举个例子,比如当前刷新浏览器,向服务器请求时间为2019-06-06 01:29:55,这时服务器返回的Date为2019-06-06 01:30:00(假设客户端到服务器的时间为5秒),config.js最近修改的时间是2019-06-06 01:00:00,Last-Modified为2019-06-06 01:00:00,(Last-Modified - Date) * 10% = 3分钟,在未来的3分钟里,你无论刷新多少次,都会走强缓存,不会请求服务器

可以看出
1.一个资源越长时间不修改,缓存的时间就会越长
2.在我们在开发中,遇到缓存的bug,想要复现,用不停的修改资源文件的方式,却很难复现的原因


zhaowenyin
369 声望22 粉丝

我会修电脑