浏览器缓存策略探索-干货-React背景

浏览器缓存策略探索-干货-React背景

技术杂谈小彩虹2021-08-16 13:52:33240A+A-

       今天这个主题也是我最近的项目里面用到的知识,原谅我这个入门前端不到两年的小菜鸡。事情是这样的,某一天我的客户爸爸和我说起最近每次新版本发布后他们打开门户网站发现时常会停留在上一个版本的内容,而且Ctr+R也没办法到最新版本,最后只能强制刷新或者清理缓存刷新才能解决,这问题一提出,我就感觉客户是要搞事情呀,多少个版本的迭代都没提出这个问题,本着客户就是上帝的原则,这个问题要解决,而且确实影响用户体验了,应该的应该的。。。这个问题提出后,我第一反应就是不应该呀,按照React的webpack打包方式,新版本打包都是自带hash的,每次刷新去拉的时候应该都是最新的了呀,因为我也是半路参与的,所以还是带着问号去看了项目里的一些配置,webpack的配置一切正常,客户这边严格贯彻gitlab的CI/CD流程,所以我也没有自己打包过,我手动打包验证webpack这里确实正常。。。。之前也遇到过这种情况,当时是我在做iOS原生开发时接入别人的h5网页发生的,当时后端的同事让我自己在链接后面加一个当前时间戳的后缀就行,这样每次都是最新的链接了,这个粗暴的方案显然不适合当前项目。

      现在回到这个主题,浏览器的缓存策略,在探索这个之前我们需要知道一个面试时经常被问到的问题,地址栏输入链接回车后到展示首页,这中间发生了什么 ?了解这个的前提下才能更好的理解,简单的说就是经过DNS解析后得到服务器的ip和端口,并前往这个ip和端口下下载我们项目的html文件,一般是Index.html,也是我们打包后的内容,浏览器会一边下载一边解析当前的html文件,当遇见css文件和js文件也立即执行这两个文件的下载,如果这里有异步的配置那就按照异步的步骤下载,这中间经过词法解析、语法解析等一系列步骤最后形成我们的首页,有兴趣的可以自行百度探索中间的奥秘,这就是上面这个问题的简单答案,那浏览器的缓存策略和这个问题有什么关联?浏览器缓存的其实就是上面的这些文件,html文件、css文件、js文件以及媒体资源如图片等,浏览器的缓存知识我在网络上搜索各种答案终于找到了一个很全面也很real的文章--zhuanlan.zhihu.com/p/44789005,这篇文章里详细的介绍了常见的缓存策略,强缓存、协商缓存、serviceWoker(这个比较高级,还不需要用到它),大家有需要自行前往查看,接下来说说我的实践以及踩的坑。

   按照上面提到的文章里面对浏览器缓存的介绍,我选择了对html文件不缓存,设置no-cache,注意这里的no-cache不是说不缓存,它还是会去浏览器比对一次,如果html文件没变化就返回304,还是使用旧的html文件,如果改变了就重新下载html文件,对js和css文件设置一个小时的缓存时间,max-age=3600,避免每次刷新都去下载文件,这里不需要担心缓存会影响更新,因为如果项目有改动,webpack打包后会给出新的hash后缀,当浏览器解析到这两个文件时发现路径已经变化了也会重新下载文件,这也是为什么对html设置不缓存的原因,这样就能保证只要有变化就一定会去下载最新的内容,我的项目里面用了nginx代理,所以就只在nginx的配置里面来配置这个缓存策略,图片如下:

通过Google的调试面板,可以看到缓存策略的体现,图片如下:

这一张html文件的下载,可以看红框内设置生效:

这一张是js文件的配置,可以看到max-age:

在做完以上缓存策略后,我联合QA以及客户爸爸,三人一起来测试效果如何,经过多轮测试后得出的结论是:ctrl+R、ctrl+shift+R、清理缓存并强制刷新这三种操作都能马上获取最新的版本内容,那需要注意的是我这里是在Google浏览器测试的,浏览器不同,这三种操作对应的背后的缓存机制也会有小的差异,这个就自己酌情处理了。

   做完这些以为可以开心摸鱼了,客户又发现图片资源没有更新。。。。不应该呀,如果是图片确实发生了变化,webpack打包也会在图片后面添加hash后缀的,webpack配置肯定没问题,我又打包一次看包内容,发现打包出来的所有图片都是没带hash后缀。ri了狗了。。。。,每次替换图片也不会去变更图片名称,谁没事闲着改名啰,所以html解析在下载图片时,发现图片路径还是之前的就取了本地缓存了,又是一顿排查。。。原因就是客户自己做开发的时候把所有图片放在了Public目录下,也就是下面这个目录:

放在这里面的好处就是设置图片src时可以不用写相对路径,比如各种../../../等,直接就是绝对路径,多么省事,如果项目里大部分的图片资源都是不经常更改的,放在这个目录里面也没什么问题,而webpack打包图片时默认是从src目录下面开始查找的,所以图片资源没有经过webpack的处理,那最后也是更改了项目里所以图片资源的加载路径,苦力活。。。这里插一句,webpack对图片处理时除了加hash,还有一个url-loader和file-loader的介入,url-loader插件时可以让你的图片在小于多少size下自动转成base64,这样图片资源就打包在代码里了,不要进行图片资源下载了,节省流量,如果项目里面小图片很多,那也会导致整体打包的size变大,也可能起到反作用,自行安排吧各位。

   在我以为终于可以摸鱼了,我还是太低估客户的搞事能力,因为项目还在内部迭代期间,发版本还是很频繁,每次更新版本后客户希望能知道当前版本的build的时间和自己最近更新版本的时间,别喷客户,我的客户自己就是开发,他希望看到开发眼里重要的内容,其实这个用版本号来记录是最形象的表达,但是考虑到客户不会提供版本号管理功能,那就考虑在package.json里面自己更新version版本,这个方案也被否决了,因为每次更新前都得手动改,容易错乱,还有其他同事再一起做项目,难以管理,最后就提出直接保存每次打包的时间,这个通过设置scripts来实现,如下:

 在index.js的入口文件里做好build time和update time的逻辑就轻松搞定:如下

 到这里这个主题就完结了,希望能帮到需要的你们,有什么疑问可以留言,大家一起讨论。

点击这里复制本文地址 以上内容由权冠洲的博客整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!

支持Ctrl+Enter提交

联系我们| 本站介绍| 留言建议 | 交换友链 | 域名展示
本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除

权冠洲的博客 © All Rights Reserved.  Copyright quanguanzhou.top All Rights Reserved
苏公网安备 32030302000848号   苏ICP备20033101号-1
本网站由 提供CDN/云存储服务

联系我们