在开发的过程当中,不少时候会遇到发布的代码没有在浏览器上及时生效,场景:html
测试:快来看,你这个bug没有改对
开发:是否是哦,强制刷新一下浏览器试试呢
测试:哦,对了...前端
但真实的用户怎么办?vue
浏览器缓存位置react
1.Service Worker (离线网页,PWA的核心技术)nginx
2.Memory Cache(内存中的缓存)算法
3.Disk Cache(硬盘中的缓存)vue-cli
4.Push Cache(推送缓存)浏览器
备注:2,3很是常见,1稍微要复杂一点,一些知名网站正在使用,如:淘宝,4没用过缓存
浏览器缓存策略服务器
1.强缓存:不会向服务器发送请求,直接从缓存中读取资源,会有以下状态:
2.协商缓存:强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存,会有以下状态:
备注:304表示虽然经历了服务器这一步,但该资源没有更新,因而继续使用缓存
1、 文件名加hash值(最多见的方式)
若是你是用的现成的脚手架,如:vue-cli, create-react-app等,别人已经帮你作好了,基本不能遇到缓存的问题
2、文件名加不了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 才是不适用任何缓存
优势:对外提供的配置文件名统一
缺点:每次都会向后台请求,由后台判断是否使用缓存,速度确定要比直接取本地的慢,但影响不大
我的建议:
若是你的文件很稳定,好比几个月,半年才修改一次,建议采用第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,想要复现,用不停的修改资源文件的方式,却很难复现的缘由