浏览器的强缓存和协商缓存

270 阅读4分钟

浏览器的缓存机制主要分为强缓存协商缓存,它们都是为了提高网页加载速度、减少服务器压力而设计的。以下是它们的详细介绍:


一、强缓存(Strong Cache)

强缓存是指浏览器在请求资源时,先检查本地缓存,如果缓存未过期,则直接使用缓存资源,而不会向服务器发送请求。

1. 实现方式

强缓存通过以下两种 HTTP 响应头实现:

  • Expires

    • 是一个绝对时间,表示资源的过期时间。
    • 例如:Expires: Wed, 21 Oct 2023 07:28:00 GMT
    • 缺点:依赖客户端时间,如果客户端时间与服务器时间不一致,可能导致缓存失效或错误。
  • Cache-Control

    • 是一个相对时间,优先级高于 Expires
    • 常用指令:
      • max-age=<seconds>:资源的最大缓存时间(单位:秒)。
      • no-cache:不使用强缓存,直接进入协商缓存。
      • no-store:禁止缓存,每次请求都从服务器获取资源。
      • public:资源可以被所有用户缓存(包括代理服务器)。
      • private:资源只能被客户端缓存。
    • 例如:Cache-Control: max-age=3600,表示资源可以缓存 1 小时。

2. 强缓存流程

  1. 浏览器请求资源时,先检查本地缓存。
  2. 如果缓存未过期(根据 ExpiresCache-Control 判断),则直接使用缓存资源。
  3. 如果缓存已过期,则进入协商缓存流程。

3. 优点

  • 减少服务器请求,提升加载速度。
  • 适用于静态资源(如图片、CSS、JS 文件)。

二、协商缓存(Conditional Cache)

协商缓存是指浏览器在强缓存失效后,向服务器发送请求,服务器通过校验资源的标识(如最后修改时间或唯一标识)来判断资源是否更新。如果资源未更新,服务器返回 304 状态码,浏览器继续使用本地缓存;如果资源已更新,服务器返回 200 状态码和新资源。

1. 实现方式

协商缓存通过以下两种 HTTP 头实现:

  • Last-ModifiedIf-Modified-Since

    • Last-Modified:服务器返回资源时,携带资源的最后修改时间。
      • 例如:Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT
    • If-Modified-Since:浏览器再次请求时,携带上次的 Last-Modified 值,服务器通过比较时间判断资源是否更新。
      • 如果资源未更新,返回 304 状态码;否则返回 200 和新资源。
  • ETagIf-None-Match

    • ETag:服务器返回资源时,携带资源的唯一标识(通常是哈希值)。
      • 例如:ETag: "123456789"
    • If-None-Match:浏览器再次请求时,携带上次的 ETag 值,服务器通过比较标识判断资源是否更新。
      • 如果资源未更新,返回 304 状态码;否则返回 200 和新资源。

2. 协商缓存流程

  1. 强缓存失效后,浏览器向服务器发送请求。
  2. 服务器根据 If-Modified-SinceIf-None-Match 判断资源是否更新。
  3. 如果资源未更新,返回 304 状态码,浏览器使用本地缓存。
  4. 如果资源已更新,返回 200 状态码和新资源。

3. 优点

  • 减少带宽消耗,避免重复传输未更新的资源。
  • 适用于频繁更新的资源。

三、强缓存与协商缓存的区别

特性强缓存协商缓存
是否发送请求不发送请求,直接使用缓存发送请求,服务器判断是否使用缓存
状态码200(from cache)304(Not Modified)
实现方式ExpiresCache-ControlLast-ModifiedETag
适用场景静态资源(长期不变)动态资源(可能更新)

四、缓存策略的最佳实践

  1. 静态资源

    • 使用强缓存,设置较长的 max-age(如一年)。
    • 通过文件名哈希(如 main.a1b2c3.js)实现缓存更新。
  2. 动态资源

    • 使用协商缓存,确保资源更新后客户端能及时获取最新版本。
  3. 禁用缓存

    • 对于敏感数据或实时性要求高的资源,使用 Cache-Control: no-store

通过合理配置强缓存和协商缓存,可以显著提升网页性能,同时减少服务器负载。