前端详解前端缓存,解决前端换包之后环境中仍会出现旧版效果
前端项目修改了很多东西:比如bug啊,样式啊。当你把前端项目打包之后满心欢喜的在 Nginx(测试环境)换上它,然后在 Jira 上修改bug状态@测试人员复测。然后测试人员开始找你battle了,你的bug怎么还是没修改啊,但是你明明换上了最新的版本,中间到底出现了什么问题。打开控制台的 network,显示如图所示。
问题就出在 from disk cache 这玩意上,也就是浏览器缓存,浏览器读取的还是缓存中旧版的资源,渲染出来的还是旧版的效果。除了 disk cache 外,还有其他几类浏览器缓存,总的来说,浏览器缓存大致分为4种,而这4种方式是有优先级顺序的,只有依次查找缓存且都没有命中的时候,才会去请求网络:Service Worker:是一种独立于主线程之外的 Javascript 线程。它脱离于浏览器窗体,可以帮我们实现离线缓存、消息推送和网络代理等功能。Memory Cache:存在内存中的缓存。包括当前中页面中已经抓取到的资源,例如页面上已经下载的样式、脚本、图片等。因为存储在内存中,MemoryCache 是响应速度最快的一种缓存,但由于同样的原因,缓存持续性很短,会随着进程的释放而释放,一旦我们关闭 Tab 页面,内存中的缓存也就被释放了。Disk Cache:Disk Cache 也就是存储在硬盘中的缓存,读取速度慢点,但是什么都能存储到磁盘中,比之 Memory Cache 胜在容量和存储时效性上。会根据 HTTP Herder 中的字段判断哪些资源需要缓存,哪些资源可以不请求直接使用,哪些资源已经过期需要重新请求。Push Cache:Push Cache 是 HTTP2 在 server push 阶段存在的缓存,当以上三种缓存都没有命中时,它才会被使用,Push Cache 是一种存在于会话阶段的缓存,当 session 终止时,缓存也随之释放。不同的页面只要共享了同一个 HTTP2 连接,那么它们就可以共享同一个 Push Cache。
其实常见的情况下只有 disk cache 和 memory cache,如下图博客园首页请求所示:
至于什么情况下是存在内存,还是存在硬盘。由于计算机内存有限,而且比硬盘容量小很多,浏览器会根据计算机具体情况来决定缓存放在内存中还是硬盘中。一般情况下,较大的 css 文件、js 文件和 jpg 图片这类大文件会被存入硬盘;当前系统内存使用率高的话,文件也会被优先存储进硬盘;而 Base64 格式的图片,几乎永远可以被塞进内存。
那为什么需要缓存呢,对前端来说,因为读缓存不需要发起请求,也就不需要考虑请求环境和速度,提高访问速度,用户体验大大提升;对于后端而言,也缓解了服务器的压力,减少网络 IO 消耗,减少带宽消耗。
但是什么时候需要缓存,什么时候不需要缓存。很明显,我这种换版操作肯定是需要重新获取新的资源的。最简单的解决办法就是 Ctrl+F5 强制刷新,强制告诉浏览器不获取缓存,必须重新去获取新的资源,但是强制刷新这种手动触发还是对用户体验不太友好。特别是我们做的后台管理系统,在图片很少的情况下,有没有办法每次换版之后都获取最新的资源。这个时候就要涉及浏览器的缓存策略了,常见的缓存策略有强缓存和协商缓存。其实浏览器的缓存策略都是通过设置 HTTP Header 来实现的。
强缓存
不会向服务器发送请求,直接从缓存中读取资源。状态码:200,显示 from disk cache 或 from memory cache。通过设置两种 HTTP Header 实现:Expires和Cache-Control。
1.Expires:值是一个时间戳,表示本地时间到这个设置的时间缓存就失效。这样一来 Expires 就是有问题的,受限于本地时间,我直接手动去把电脑端的时间改掉,都能导致缓存失效,所以更推荐使用 Cache-Control,或者二者搭配使用。
在 Nginx中配置写法如下:# gif、jpg、jpeg、png、bmp、ico这类的资源会在30天后失效 location ~ .(gif|jpg|jpeg|png|bmp|ico)$ { root /XXXX/xxxx; expires 30d; }
2.Cache-Control:优先级比 Expires 高,同时设置 Expires 和 Cache-Control 则后者生效。可以在请求头或者响应头中设置,并且可以组合使用多种指令:private(默认):只能在浏览器中缓存, 只有在第一次请求的时候才访问服务器,若有 max-age,则缓存期间不访问服务器 public:可以被任何缓存区缓存,如:浏览器、服务器、代理服务器等 no-cache:可以缓存,但每次都应该去服务器验证缓存是否可用,进入协商缓存阶段,若有 max-age,则缓存期间不访问服务器, no-store:不仅不能缓存,连暂存也不可以(即:临时文件夹中不能暂存该资源) max-age=:以秒为单位的缓存时间,max-age=60,表示缓存60秒后失效,60秒内再次访问该资源,均使用本地的缓存,不再向服务器发起请求 s-maxage=:同 max-age 作用一样,只在代理服务器中生效(比如CDN缓存),s-maxage 优先级高于 max-age,只对 public 缓存有效。设置了 s-maxage,没设置 public,代理服务器也可以缓存这个资源 must-revalidate:可缓存但必须再向源服务器进确认 proxy-revalidate:要求中间缓存服务器对缓存的响应有效性再进行确认
在 Nginx 中配置写法如下,随便举一个指令:location ~ .*.(css|js|swf|php|htm|html )$ { add_header Cache-Control no-store; }
协商缓存
当 Cache-Control 和 Expires 过期或者它的属性设置为 no-cache 时(即不走强缓存),那么浏览器第二次请求时就会与服务器进行协商,服务器端会对比判断资源是否进行了修改更新,对比结果无非是以下两种:如果服务器端的资源没有修改(Not Modified),那么就会返回304状态码,告诉浏览器可以使用缓存中的数据。 如果数据有更新就会返回200状态码,服务器就会返回更新后的资源并且将缓存信息一起返回。
至于浏览器是怎么和服务器交互,主要是依靠跟协商缓存相关的header头属性:Last-Modified/If-Modified-Since、ETag/If-None-Match。这些属性在请求头和响应头是成对出现的。
1.Last-Modified/If-Modified-Since:
浏览器在第一次访问资源,或缓存过期后访问,服务器返回资源的同时,在 response header 中添加 Last-Modified 的 header,值是这个资源在服务器上的最后修改时间,浏览器接收缓存文件和header信息。随后我们每次请求时,浏览器会自动带上一个叫If-Modified-Since 的时间戳字段给服务器,它的值正是上一次 response 返回给它的 Last-modified 值,然后服务器会根据 If-Modified-Since 的值对比资源的最后修改时间判断资源是否进行了修改更新。
2.ETag/If-None-Match :
Etag是由服务器为每个资源生成的唯一的标识字符串,这个标识字符串是基于文件内容编码的,只要文件内容不同,它们对应的 Etag 就是不同的,因此 Etag 能够精准地感知文件的变化。Etag 和 Last-Modified 类似,当首次请求时,我们会在响应头里获取到一个最初的标识符字符串。那么下一次请求时,浏览器就会在请求头里就会带上一个值相同的、名为 if-None-Match 的字符串供服务器比对。Etag 的优先级会比 Last-Modified 高,但是Etag因为要生成,也会更消耗服务器性能。
查看 Nginx 更新日志可知,在2014年6月26日就默认开启 Etag,对应的版本为1.7.3,也就是说1.7.3及以上的版本的 Nginx 默认开启 Etag。不过需要注意的是,如果 Nginx 有开启 Gzip,可能会与 Etag 有冲突。
然后就是各家的 Etag 生成情况都不太一样,取决于服务器的类型或配置的算法。以下是简书首页随便的一个请求,这个不是什么大问题,顺便提一嘴。
说了这么多,前端缓存最理想的效果就是希望能尽可能多的命中强缓存,对于频繁变动的资源,多使用协商缓存,同时,能在更新版本的时候让浏览器的缓存失效。这就要求了我们对资源进行 Nginx 配置的时候,对资源失效时间有个自己的衡量和把握。
最后,还有一种情况是浏览器在几次刷新过程中会出现新版效果,也会出现旧版效果,新旧交替。那就得考虑前端项目是否布置了多节点,并使用 Nginx 配置负载均衡了,如果是这个问题的话,只要全部 Nginx 节点环境都换上新打的前端包问题就迎刃而解了。
文章来源:https://www.cnblogs.com/jdWu-d/p/12918311.html
为什么胡亥能够稳坐皇位?为了能够坐稳皇位,胡亥大开杀戒,威慑他人,除掉威胁他的人,让朝野臣服在他的脚下。早在胡亥即位之前,胡亥赵高李斯就已经伪造圣旨,派遣使者前往远守大秦疆域的蒙恬扶苏北上,命蒙恬扶苏自尽
山西最后一任巡抚陆钟琦1北京人陆钟琦,顺天宛平(今北京市)人。2正统文化的继承者(1)陆钟琦自幼受到传统教育,思想保守,忠君思想严重。(2)他寒窗苦读,光绪十五年进士,做过溥仪父亲载沣的老师。比较有学问
1876年杨乃武与小白菜冤案为何能得到慈禧亲自下谕旨?说起杨乃武与小白菜的冤案,想必是家喻户晓。但是,说到这一著名冤案的昭雪与胡雪岩的大力相助是有很大关系的,知道这个的人恐怕就不是很多了吧。清朝末年发生的所谓四大奇案,杨乃武与小白菜一
老江北县地名探寻两个麻柳原四川省江北县,旧境南濒长嘉两江,北倚华蓥山宝鼎主峰,面积1944。23平方公里,人口101。59万(1990年)。江北县域内五岭四槽,浅谷低丘,溪流蜿蜒,广有洞泉,气候温和,空间
唐朝灭亡主要原因藩镇割据安史之乱后,为何还能苦撑150年之久阅读此文前,诚邀您点击一下关注,既方便您进行讨论与分享,又给您带来不一样的参与感,感谢您的支持。自李唐开世,华夏大地复又呈现出一副好颜色。九天宫殿现万国衣冠,琥珀玉碗盛兰陵美酒。文
二哈中的国家土耳其在抗美援朝时期,土耳其为了抱住美国的大腿,曾拍了5000,您土耳其士兵来到抗美援朝战场上,原本是遇到了中国志愿军,于是打了一仗,干掉了500人,俘虏了200人,但当他们带着200俘
1995年东莞殡仪馆18岁女尸离奇复活,11年后跪谢恩人震撼人心情感点评大赏好内容我来评娱评大赏1995年东莞殡仪馆18岁女尸离奇复活,11年后跪谢恩人,背后真相震撼人心作者暮暮秋水编辑贾方方来源婚姻与家庭杂志IDhunyinyujiating
1936年,张学良出资送3个孩子秘密去苏联,其中2个竟是毛泽东儿子历史开讲张学良前言1936年,张学良得知董健吾要送三个孩子到苏联,他没有询问孩子的身份,直接就说三个孩子的出国费用由我负责,然后就掏出了一张10万法郎的支票。张学良不知道的是,其中
帐篷草地派对湖州的春天就该这么玩全面权威深度专业春风拂面,鸟语花香灵粮农场房车营地吃住娱满足您关于农场的所有畅想营地为了满足不同的家庭亲子需求设置有湖景亲子榻榻米房湖畔庭院大床房湖畔庭院双床房房间内设施齐全,给人
李在明案又一证人离奇身亡,没了文在寅帮忙,他还能逃过一劫吗?前几天差点被逮捕的韩国最大在野党党首李在明,又摊上事了。韩国最大在野党共同民主党党首李在明据环球网报道,李在明担任京畿道知事时的首任秘书室长全亨洙,被发现在家中离奇死亡。按照警方的
真相大白,艾菲尔丁年龄造假事件反转,国足队长摊牌,六字真硬气最近国足U20已经取得八强的入场券,接下来在亚洲杯的淘汰赛中,将会去面对韩国队争夺四强的门票。如果能够进入四强,将可以直接拿到直通世青赛的门票。所以对于中国队来说,接下来一定要好好