mfc中picture control的用法_Cache-Control 的 stale-while-revalidate 指令

bbfd0a2030bd4227c1cdce00d76b535a.png

英文单词 stale 的意思是陈旧的,不新鲜的。在 HTTP 缓存领域,stale 用来形容一个缓存过期了,比如说是max-age指定的缓存时间到了。

一个资源的缓存过期之后,如果想再次使用它,需要先对该缓存进行 revalidate。在 revalidate 执行期间,客户端就得等待,直到 revalidate 请求结束,在一些特别注重性能的场景下,这种传统的同步更新缓存的机制被认为是有性能问题的。

2010 年的时候,雅虎的工程师 Mark Nottingham 为Cache-Control响应头制定了两个新的扩展指令 https://tools.ietf.org/html/rfc5861, 其中一个就是stale-while-revalidate

while 在英文里是“当…的时候”、“和…同时”的意思,所以stale-while-revalidate就是说当 revalidate 请求进行时,客户端可以不等待,直接使用过期的缓存,revalidate 完了缓存就更新了,下次用的就是新的了。所以stale-while-revalidate实现的功能用通俗的词语解释就是“后台缓存刷新”、“异步缓存更新”之类的。

stale-while-revalidate的用法和max-age类似,需要指定一个秒数作为参数。比如Cache-Control: max-age=60, stale-while-revalidate=3600是说,这个缓存在 60 秒内是新鲜的,从 60 秒到 3660 秒的这一个小时内,虽然缓存是过期了,但仍可以直接使用这个过期缓存,同时进行异步 revalidate,在 3660 秒之后,就是完全过期了,需要进行传统的同步 revalidate。

看图说话更清晰一点:

ab475020052be4a68f501c48f5f9d8e7.png
stale-while-revalidate 缓存刷新

stale-while-revalidate最初是为缓存服务器设计的,所以 varnish、squid、nginx 这些软件都已经支持它。不过我不清楚国内的 CDN 厂商有没有支持它的,至少我没看到任何一家的文档有提到它,所以猜测大概率都是不支持的。国外的 CDN 的话,从 http://cdncomparison.com/ 这个网站收集的信息来看,亚马逊不支持,阿卡迈未知,另外还有一些 CDN 厂商是支持的,不过总体来说是个略小众的特性。

在浏览器端呢,8 年来一直没有浏览器实现,Chrome 尝试实现过,两次!但都失败了,因为 Chrome 自己的架构问题。2018 年至今的这第三次尝试,成功了,目前已经在 Chrome 75 中默认开启,Chrome 同时还推动它进了 https://fetch.spec.whatwg.org/ 规范,接着 Firefox 也在上个月迅速实现了。

stale-while-revalidate指定的时间段内读取缓存的话,Chrome DevTools 里除了能看到本身的那个直接读取过期缓存的请求(200),还可以看到异步刷新缓存的请求(304):

61ddaa2ba8ca260eb9d1c62a0ca82a30.png
stale-while-revalidate Chrome DevTools 调试

Firefox DevTools 里目前看不到后者。

还有一个需要想清楚的地方,就是过期的缓存在刷新之后就不再是过期缓存了,而是会重新开启一次全新的生命周期,stale-while-revalidate指定的那个时间段并不是一定会经历完全。

14b7d59a87cf23802dc3ae444f1fc77f.png
stale-while-revalidate 重新计算缓存时长

上面有说到stale-while-revalidate在 CDN 上的应用其实并不广泛,那在浏览器端,我们有这样的需求吗?大家都知道现在大部分静态资源都是非覆盖式发布,发一个新版本就会去改变这个资源 URL 中的版本号或者 hash 值,这种情况下,该资源的缓存时长会设置特别大,比如一年、三年甚至十年,在它到期之前,早就已经不在线上使用了,也就是说它永远都不会过期。stale-while-revalidate对非覆盖式发布的资源没有用处。

不过总有一些场景,资源的 URL 是不能变的,比如网站首页,例如 https://www.taobao.com/(淘宝首页是可缓存的静态页面);又或者说要变 URL 的话成本很大,比如要交给第三方使用的 URL。这些场景下 stale-while-revalidate才可能派上用场。

stale-while-revalidate是为了加载速度牺牲了资源的新鲜性(通常就牺牲一次),但有些场景下,可能一次也无法接受,比如就说淘宝首页,给它指定个一天的 stale-while-revalidate,那假如用户在双十一前一天访问过首页,页面会被缓存下来,然后第二天也就是双十一早上再打开,可能会发现页面和昨天一模一样,并没有双十一氛围的样式,虽然只有一次,但可能也无法接受。

所以说 stale-while-revalidate该不该用,该用多大的数字,需要自己视情况而定。不过就我目前的理解,stale-while-revalidate大、max-age小应该是主流的选择。甚至极端一点的Cache-Control: max-age=0, stale-while-revalidate=36000000 有应用场景也说不定。

上篇文章中讲到的 must-revalidate指令,可以屏蔽 stale-while-revalidate指令,比如:

Cache-Control: max-age=60, stale-while-revalidate=3600, must-revalidate

或者再追加一个单独的 Cache-Control响应头:

Cache-Control: max-age=60, stale-while-revalidate=3600
Cache-Control: must-revalidate 

但为何不直接把 stale-while-revalidate指令直接删掉?所以must-revalidate 仍然是个不应该去使用的东西。

如果你有能用到stale-while-revalidate 的场景,甚至已经在 CDN 上使用了它的,不妨在下面留言说说。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值