浏览器缓存策略

浏览器缓存阶段

  • 强缓存阶段
  • 启发式缓存阶段
  • 协商缓存阶段

浏览器缓存机制

缓存流程

浏览器缓存流程

如上图,浏览器在首次访问网站的时候(第一次发起HTTP请求),由于浏览器缓存没有该网站信息,所以浏览器直接发起HTTP请求。

网站(服务器)处理请求后,返回的response header中,包含请求结果和缓存规则,这里的缓存规则也就是后面会讲到的强缓存和协商缓存的相关字段。

当浏览器第二次访问该网站的时候,就会结合缓存信息进行相应的判断,判断是否使用强缓存、协商缓存

强缓存 —— 直接使用缓存

相关字段:Cache-Control、expires

强缓存利用HTTP头中的Expires和Cache-control连个字段来控制,这两个字段用来表示资源的缓存时间。

Expires

http1.0规范,Expires的值是一个绝对时间GMT格式的时间字符串
例如:Expires: Fri Nov 08 2019 09:39:47 GMT+0800 (中国标准时间),表示这个资源过期的时间是2019年11月8日的09:39:47,只要发送请求的时间在expires之前,资源就有效

PS:浏览器或服务器其中一端时间错误,影响缓存准确性

Cache-control

http1.1中出现的,主要利用该字段的max-age值来判断,max-age的值是一个相对时间。
例如:Cache-control: max-age=300,表示资源有效期300秒。

Cache-control字段的其他值

Cache-control字段取值

不同取值可以组合使用,组合使用方式
组合使用

各值存在优先级,在此不做展开

优先级:Cache-control > Expires

协商缓存 —— 强缓存失效

相关字段: Etag、Last-Modified

协商缓存是在强缓存失效的时候,客户端将协商缓存相关的字段,转换成特殊字段加到请求头里,交由服务器来判断缓存资源是否可用。

个人理解:注意,这里指的强缓存失效,并不是缓存失效,只是服务器设定的一个有效期,过了这个时间,客户端应该需要向服务器询问,本地的缓存是否过期,是否需要更新。

对于Etag和Last-Modified字段,在请求服务器时,会转换成If-None-Match和If-Modified-Since放到请求头中。也就是,第一次请求,服务器返回Etag和Last-modified字段,后续请求会带上If-None-Match和If-Modified-Since字段去询问服务器。

Etag / If-None-Match

Etag 是资源的标识符。
可以保证每一个资源是唯一的,资源变化都会导致 Etag 变化。服务器根据浏览器上送的 If-None-Match 值来判断是否命中缓存

Last-Modified / If-Modified-Since

Last-Modified 是一个时间标识该资源的最后修改时间。
例如 Last-Modify: Thu,31 Dec 2037 23:59:59 GMT

优先级:Etag > Last-Modified

为什么要有Etag

Last-Modified似乎已经可以完成协商缓存的作用,为什么需要Etag。并且Etag的优先级更高呢?

  • 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;
  • 某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);
  • 某些服务器不能精确的得到文件的最后修改时间。

浏览器缓存机制流程图

浏览器缓存机制流程图

启发式缓存

  • 没有任何关于缓存的字段 —— 不设置任何缓存策略
  • 常会取响应头中的 Date 减去 Last-Modified 值的 10% 作为缓存时间

参考

文章作者: ptp
文章链接: https://youyingjie114.github.io/2019/11/08/FE-basic/knowledge-network/%E6%B5%8F%E8%A7%88%E5%99%A8%E7%BC%93%E5%AD%98%E6%9C%BA%E5%88%B6/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 PTP'S BLOG