浅析HTTP缓存

前言

没有缓存的浏览器是无源之水、无根之木,需要通过不等次数的网络来回获取资源,而网络情况是不确定的,所以网络请求一直被我们视为洪水猛兽。

所以不管是为了加快用户访问速度、改善用户体验,还是节约流量,存储之前获取的资源并留待以后重复利用势在必行。

HTTP缓存主要是根据HTTP协议的约定,主要还是服务端通过HTTP头部字段等进行控制,客户端接收到相关字段并进行相应缓存存储以及命中逻辑。

所以到底有哪些重要字段呢?

1. Cache-Control

  1. max-age
    设置缓存最大有效期,单位为s,定义的是时间长短,需要配合时间字段使用,如Date。在max-age设定的有效期内,浏览器发出的请求会直接命中HTTP缓存,不会进入网络堆栈。
  2. s-maxage
    用法同max-age,不过该字段只用于共享缓存(比如CDN缓存),当处理代理缓存时,如果存在s-maxage,那么其会覆盖掉max-age和expires。同理如果在s-maxage有效期内,即使CDN资源发生了改变,浏览器请求也不会进入网络堆栈。
  3. no-cache
    不缓存响应,表示必须先和服务器确认返回的响应是否发生了变化,然后才能使用该响应来满足后续请求命中缓存。场景一般是资源变化比较迅速,所以强制启用ETag进行资源验证,如果ETag等验证通过,则可以返回304
  4. no-store
    绝对禁止浏览器以及中间缓存存储任何版本的响应,场景一般是个人隐私数据或者安全性比较高的银行数据等,强制要求每次请求资源必须进行用户验证和网络来回。
  5. public
    相对于private是默认值,即使存在HTTP用户认证等限制,缓存也会被响应,并且允许多用户共享,比如CDN。
  6. private
    只作为私有的缓存,不能再用户间共享,不允许任何中间缓存对其进行缓存,比如CDN。如果要求HTTP认证,响应会自动设置为private。

HTTP Cache-Control属性决定树

2. Expires

缓存过期时间,是具体的时间点,即绝对时间,数值上等于max-age + new Date().getTime() 。其优先级相对Cache-Control略低,主要用作兼容旧浏览器,具体作用与Cache-Control的max-age类似。

3. Last-Modified

语义为资源最后修改时间,经常配合Cache-Control使用,是检查资源更新的重要字段。当浏览器请求资源并且缓存已经不再有效期内或者no-cache,那么我们需要进行网络来回确认资源是否修改,此时浏览器根据Last-Modified会生成if-Modify-Since,服务端接收比对后如果没有修改则返回304,直接使用缓存,如果修改了,则请求服务器最新资源。

4. ETag

服务端根据一定规则生成的hash字符串、UUID或类似物,用来进行资源状态唯一标识,其作用过程如下:

ETag过程

其实作用与Last-Modified有重叠,我们只需比对修改时间是否一致即可,为何还要比对ETag字符串呢?

因为Last-Modified存在如下问题:

  1. 某些服务器不能精确得到资源的最后修改时间
  2. 如果资源修改非常平凡,在秒级别之下的时间内进行修改,而Last-Modified只能精确到秒
  3. 当资源最后时间修改过了,但内容没变时,ETag不会变化,可以有效区分这种情况

大概就讲这四个关键的header,如果想了解其他的header,可以看我另一篇博客HTTP协议知多少

总结

所以综上所述,HTTP缓存的流程为:

HTTP缓存响应流程

在制定缓存策略时,您需要牢记下面这些技巧和方法:(来自谷歌开发者《HTTP缓存》)

  • 使用一致的网址:如果您在不同的网址上提供相同的内容,将会多次获取和存储这些内容。提示:请注意,网址区分大小写。
  • 确保服务器提供验证令牌 (ETag):有了验证令牌,当服务器上的资源未发生变化时,就不需要传送相同的字节。
  • 确定中间缓存可以缓存哪些资源:对所有用户的响应完全相同的资源非常适合由 CDN 以及其他中间缓存进行缓存。
  • 为每个资源确定最佳缓存周期:不同的资源可能有不同的更新要求。为每个资源审核并确定合适的 max-age。
  • 确定最适合您的网站的缓存层次结构:您可以通过为 HTML 文档组合使用包含内容指纹的资源网址和短时间或 no-cache 周期,来控制客户端获取更新的速度。
  • 最大限度减少搅动:某些资源的更新比其他资源频繁。如果资源的特定部分(例如 JavaScript 函数或 CSS 样式集)会经常更新,可以考虑将其代码作为单独的文件提供。这样一来,每次获取更新时,其余内容(例如变化不是很频繁的内容库代码)可以从缓存获取,从而最大限度减少下载的内容大小。

参考

  1. 浅谈 Web 缓存
  2. 浅谈浏览器http的缓存机制
  3. HTTP缓存控制小结
  4. RFC文档
  5. 谷歌开发者HTTP缓存
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值