[学习笔记整理] 浏览器缓存策略

327

把之前学习的笔记整理发布到博客,虽然大部分是复制粘贴,不过对于个人而言也是精炼了。引用都会标注出来~

浏览器缓存策略

两类缓存

  • 强缓存(本地缓存)

  • 协商缓存(弱缓存)

    浏览器缓存分为两个阶段,本地缓存阶段与协商缓存阶段,也就是以上两个顺序为先判断强缓存再判断协商缓存。

本地缓存阶段

浏览器发送请求之前,会先去缓存里查看是否命中强缓存,如果命中,则直接从缓存读取资源,不发送请求。否则,进入协商缓存阶段。

缓存规则

当浏览器第一次向服务器请求资源时,服务器会将缓存规则放入HTTP响应报文的头部和请求结果一起返回给浏览器,控制强缓存的字段分别是ExpiresCache-Control,两个可以同时启用,同时启用时Cache-Control优先级更高。

  • Expires

    Expires是HTTP/1.0控制网页缓存的字段,其值为服务器返回的请求结果的过期时间,这是一个绝对时间:Mon Aug 30 2021 11:26:16 GMT+0800 (中国标准时间)。如果超过了这个绝对时间,缓存便会失效。

  • Cache-Control

    Cache-Control是HTTP/1.1的字段,它也有几个可选取值:

    ​ public: 所有内容都将被缓存(客户端和代理服务器都可缓存)

    ​ private: 所有内容只有客户端可以缓存,Cache-Control的默认取值

    ​ no-cache: 客户端缓存内容,但是是否使用缓存则需要经过协商缓存来验证决定

    ​ no-store: 所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存

    ​ max-age=xxx: 缓存内容将在xxx秒后失效

    其中max-age=xxx中,xxx是一个以相对时间,这避免了使用Expires时由于某些原因客户端与服务器时间会出现误差,而导致强缓存失效的情况。

协商缓存阶段

如果没有命中强缓存,浏览器一定会发送一个请求到服务器,通过last-modifiedetag验证资源是否命中协商缓存,如果命中,服务器会将这个请求返回并且不会返回请求所需的资源数据,仍然让浏览器从缓存中读取资源,如果没有命中则服务器会返回请求数据。

协商缓存通过[Last-Modified,If-Modified-Since]和[ETag,If-None-Match]来判断是否命中缓存。

  • Last-Modified,If-Modified-Since

    Last-Modified的值是文件的最后修改日期,Last-Modified是浏览器在第一次发送请求时服务器响应时headers中所带的一个字段。在之后的浏览器请求,浏览器端都会在headers中带上If-Modified-Since这个字段,值为Last-Modified的值,服务器通过判断If-Modified-Since的值和文件的最后修改日期来确实是否可以使用缓存,可以使用缓存则返回304。

  • ETag,If-None-Match

    ETag是一个字符串的资源标识,属于HTTP/1.1,ETag可以保证每个资源都是唯一的,资源变化都会导致ETag变化。ETag跟last-modified类似都是浏览器第一次发送请求时服务器返回的字段,再之后的请求中浏览器都会在headers的If-None-Match中带上ETag的值发送给服务器,服务器根据If-None-Match的值来判断是否可以使用缓存,可以使用缓存则返回304,不可以则返回最新的资源和新的Etag值。Etag的优先级比Last-Modified更高。

为何需要使用ETag?

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

浏览器缓存整体流程图

672fb4ce-28f9-498d-9140-b3ff9f47d62f

参考

缓存(一)——缓存总览:从性能优化的角度看缓存

缓存(二)——浏览器缓存机制:强缓存、协商缓存