微信小程序图片缓存策略

昨天,后端给我提了一个问题:他更换了CDN上的图片,但是他打开小程序来看,还是旧图片,他尝试过删除小程序,重新进,还是旧图片。

我第一反应是:“你有没有清CDN缓存?“

他说:”我在阿里云CDN控制台刷新缓存了,都两三天了,还是旧图片。”(后来我看过刷缓存记录,一天前刚刷的,他夸张了。。。)

我说:“那不应该呀,CDN刷新缓存,5分钟就生效了。”

当即拿出我的手机,进小程序看了一下,是新的图片。

他赶紧拿出他的手机给我看,果然,不管试多少次,都是旧图片。

我说:”你这个图片是文件名没改,请求地址没变,被客户端缓存了。但是这个没关系,你这个图片基本上不会换,这次换图,在我手机上已经验证了是没问题的,并且图片所在的模块是新增的,目前还没发布,用户没有访问记录,他们手机上没有旧图的缓存,发布后,用户手机上都会看到新图片,你手机上的旧图只是测试的时候访问过,就被缓存了。“

但是,他不同意,说:“万一后面又要换图了,那怎么办?”

虽然他说的万一概率很小,但是不怕一万就怕万一。我只好跟他说:”那行,我处理下“

很简单嘛,改文件名就好了。但是他这些图片名称都是按商品类目名称批量生成的,而且如果改文件名,他要改代码,我也要改代码。

那就不改文件名,在图片地址后面加查询字符串嘛,哪张图片变了,就把它地址后面的查询字符串改一下,比如?v=1?v=2,这样他就不用改代码了,但是前端还是要改代码,每次图片变了,我得改小程序里引用这张图片地址后面的查询字符串,这还要重新发布。

这个方法太笨了,直接在图片地址后面生成时间戳不就好了,如:${url}?ts=${new Date().getTime()}。但是这样图片每次都会重新请求,性能会产生问题。

那为什么图片会被缓存那么久了?怎样才能让缓存失效了?

打开控制台看下请求,如下:

WechatIMG528.jpeg

 

从控制台里可以看到,图片响应是from disk cache,说明图片资源被缓存到磁盘了,disk cache是强缓存,它是持久存储。但是disk cache是会严格根据HTTP头信息中的缓存控制字段来判定哪些资源可以缓存,缓存多久的。我们可以在HTTP响应头里设置Cache-ControlExpires来告诉小程序,这个图片应不应该被缓存,如果缓存,应该缓存多久。

可以看到,上图中,我的图片响应头里是没有Cache-ControlExpires的,所以当你没有在响应头里设置缓存策略时,小程序会强缓存你的图片,而且会缓存很久很久;

在我的需求里,我这个图片不会经常变动,就算变了,一天后生效也是OK的,所以我给这个图片的响应头加上Cache-Control: max-age=86400就可以了,max-age以秒为单位,8640024小时

这样设置以后,用户第一次访问图片会被小程序缓存,24小时内用户再次访问此图片,小程序不会发出网络请求,而是直接从磁盘缓存里读取。24小时以后,缓存过期,用户再次访问此图片时,小程序会发出请求从服务器获取最新图片。

我的图片是放在阿里云上的,应该如何设置响应头呢?

虽然图片是从CDN请求,但是我们CDN源站设置的是阿里云对象存储OSS的Bucket域名,对象存储OSS可以设置资源的HTTP响应头。

登录阿里云,进入对象存储OSS,找到资源所在Bucket-文件管理,进入资源所在目录,资源列表右边“更多”里有“设置HTTP头“,除了可以设置单个资源的HTTP头,还可以选择当页所有资源,批量设置HTTP头。点击“设置HTTP头“,在“Cache-Control"字段填上值保存就可以了,如下图:

WechatIMG533.jpeg

除了刚才说的强缓存,还有一种协商缓存策略,再看我之前贴的那个图片响应的图,响应头里虽然没有Cache-ControlExpires,但是有ETagLast-Modified,上面说当disk cache过期后,小程序会重新向服务端发起请求,此时客户端会在请求头带上上一次图片响应的ETagLast-Modified,分别放在If-None-MatchIf-Modified-Since里,服务器接受到这两个字段后,会和当前资源比较,如果ETag变了,或者资源修改时间大于上次修改时间,将返回新资源,否则返回304告诉客户端,资源没有变化。



作者:不吃瓜的码农
链接:https://www.jianshu.com/p/65710ab69c3b
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值