缓存相关 | 青训营

40 阅读4分钟

强缓存和协商缓存是浏览器缓存机制中的两种常见策略,用于提高网页加载速度和减少网络流量。他们也是前端面试中经常考到的计网相关知识点,今天我们一起来梳理学习一下。

🐘 强缓存

强缓存的含义是,客户端发送请求时,会先访问缓存数据库,存在就直接返回,否则再向服务器发送请求。

可以造成强缓存的字段是 cache-controlExpires.

Expires表示缓存到期的时间,是一个绝对的时间.

Expires: Thu, 10 Nov 2017 08:45:11 GMT

缺点:

  1. 由于是绝对时间,考虑到时差/误差或者客户端自行修改等因素,都会造成客户端与服务器端时间不一致,从而导致缓存失效。
  2. 字段表示过于复杂,很容易因为非法属性值从而设置失效

cache-control 则是通过设置相对时间来修正 Expires 的缺点.

Cache-control: max-age=2592000

更多常用的字段

  • max-age:即最大有效时间,在上面的例子中我们可以看到
  • must-revalidate:如果超过了 max-age 的时间,浏览器必须向服务器发送请求,验证资源是否还有效。
  • no-cache:虽然字面意思是“不要缓存”,但实际上还是要求客户端缓存内容的,只是是否使用这个内容由后续的对比来决定。
  • no-store: 真正意义上的“不要缓存”。所有内容都不走缓存,包括强制和对比。
  • public:所有的内容都可以被缓存 (包括客户端和代理服务器, 如 CDN)
  • private:所有的内容只有客户端才可以缓存,代理服务器不能缓存。默认值。

🦄 协商缓存

当强制缓存失效(超过规定时间)时,就需要使用协商缓存,由服务器决定缓存内容是否失效。

大致流程如下:浏览器先请求缓存数据库返回一个缓存标识,随后携带这个缓存标识与浏览器通讯,如果未失效则返回 304 继续使用,否则返回新的数据与缓存规则。

协商缓存具有两组字段:

Last-Modified & If-Modified-Since

  1. 服务器通过 Last-Modified 告知客户端,资源最后一次被修改的时间.
  2. 浏览器将这个值和内容一起记录在缓存之中.
  3. 下一次请求相同资源而强缓存失效时,会在请求头中设置 If-Modified-Since 的值为缓存中记录的 Last-Modified.
  4. 服务器会将 If-Modified-Since 的值与 Last-Modified 字段进行对比。如果相等,则表示未修改,响应 304;反之,则表示修改了,响应 200 状态码,并返回数据。

缺陷如下:

  • 如果资源更新的速度是秒以下的单位,那么该缓存是无法使用的。
  • 如果文件是通过服务器动态生成的,那么该方法的更新时间永远是生成的时间,尽管文件可能并没有改变,但仍然会被认为改变了。

Etag & If-None-Match

为了解决上述问题,出现了这一组新的字段。

Etag存储文件的特殊标识(通常由hash生成),流程基本一致。

🎯 策略选择

  • 强缓存适用于那些不经常更新的静态资源,例如图片、样式表等。它可以减少对服务器的请求,提高网页加载速度。
  • 协商缓存适用于那些经常更新的资源,例如动态生成的内容或者频繁变动的数据。它可以通过与服务器进行通信来判断资源是否有更新,从而决定是否使用缓存。

📝 小结

如果有强制缓存且未失效,则使用强制缓存,不请求服务器,状态码均为 200.

如果有强制缓存但已失效,则使用协商缓存,比较 时间 或 Etag 确定是 304 还是 200.