深入理解浏览器缓存机制:强缓存与协商缓存

510 阅读5分钟

在日常开发中,我们经常听到“缓存”这个词。合理利用缓存不仅能显著提升页面加载速度,还能减轻服务器压力。而浏览器缓存作为最基础也是最重要的性能优化手段之一,掌握其工作原理至关重要。

本文将带你系统梳理浏览器缓存的核心机制——强缓存协商缓存,并通过图解方式帮助你彻底搞懂它们的工作流程。


一、为什么需要浏览器缓存?

当用户首次访问一个网页时,浏览器会下载 HTML、CSS、JS、图片等资源。如果每次刷新或跳转都重新请求这些资源,不仅耗时长、占用带宽,还会增加服务器负载。

浏览器缓存的作用就是:在一定时间内复用已下载的资源,避免重复请求,提升用户体验。

缓存策略主要分为两类:

  • 强缓存(Strong Cache)
  • 🔁 协商缓存(Revalidation Cache)

下面我们逐一详解。


二、强缓存:直接从本地拿资源

1. 什么是强缓存?

强缓存是指浏览器在接收到服务器响应时,根据响应头中的过期策略,判断资源是否“未过期”。如果未过期,则直接从本地缓存读取资源,不再向服务器发起请求。

此时,网络面板中该资源的状态码显示为:

200 OK (from disk cache)(from memory cache)

2. 控制强缓存的头部字段

字段协议版本说明
Cache-ControlHTTP/1.1 ✅推荐使用,优先级更高
ExpiresHTTP/1.0 ⚠️已过时,兼容用

Cache-Control(推荐)

常见取值:

  • max-age=3600:资源最多缓存 3600 秒(1小时)
  • no-cache:不使用强缓存,但可走协商缓存
  • no-store:禁止任何缓存,每次都请求服务器
  • public:资源可被所有中间节点缓存(如 CDN)
  • private:仅客户端可以缓存,中间代理不可缓存
Cache-Control: max-age=3600, public

📌 注意:Cache-Control 优先级高于 Expires

⚠️ Expires

指定资源的绝对过期时间(GMT 格式):

Expires: Wed, 31 Aug 2025 07:00:00 GMT

但由于依赖客户端时间,容易因时间不同步导致问题,现已不推荐单独使用。

3. 强缓存工作流程图

image.png

图解:浏览器收到响应后检查 Cache-ControlExpires,若未过期,则直接使用本地缓存,不发请求。


三、协商缓存:让服务器决定是否更新

1. 什么是协商缓存?

当强缓存失效(即资源已过期),浏览器不会立刻下载新资源,而是发起一次请求询问服务器资源是否有更新。这个过程称为“协商缓存”。

如果资源未变,服务器返回 304 Not Modified,告诉浏览器继续使用缓存;否则返回 200 和新资源。

2. 协商缓存的两种机制

方式一:Last-Modified / If-Modified-Since

  • 首次请求,服务器返回:
    Last-Modified: Tue, 26 Aug 2025 10:00:00 GMT
    
  • 后续请求,浏览器自动带上:
    If-Modified-Since: Tue, 26 Aug 2025 10:00:00 GMT
    
  • 服务器对比时间:
    • 资源未修改 → 返回 304
    • 资源已修改 → 返回 200 + 新资源

⚠️ 缺点:时间精度为秒级,且文件内容未变但修改时间变了也会误判。

方式二:ETag / If-None-Match(推荐)

  • 首次请求,服务器生成资源唯一标识:

    ETag: "abc123xyz"
    

    (通常是内容哈希或版本号)

  • 后续请求,浏览器带上:

    If-None-Match: "abc123xyz"
    
  • 服务器对比 ETag:

    • 一致 → 返回 304
    • 不一致 → 返回 200 + 新资源

✅ 优点:精确到内容级别,即使时间没变但内容变了也能检测到。

🔥 优先级:ETag > Last-Modified

3. 协商缓存工作流程图

协商缓存流程图转存失败,建议直接上传图片文件

图解:强缓存失效后,浏览器携带 If-Modified-SinceIf-None-Match 发起请求,由服务器判断是否返回 304


四、完整缓存(建议收藏)

整个缓存流程如下:

  1. 用户发起请求
  2. 浏览器检查是否存在强缓存(Cache-Control / Expires
    • ✅ 未过期 → 使用本地缓存(200 from cache
    • ❌ 已过期 → 进入协商缓存
  3. 发起请求,携带 If-Modified-SinceIf-None-Match
  4. 服务器比对资源
    • 未修改 → 返回 304,使用缓存
    • 已修改 → 返回 200 + 新资源

五、实际开发中的缓存策略建议

资源类型建议缓存策略
HTML 文件Cache-Control: no-cache 或短时间缓存 + ETag
CSS/JS 静态资源Cache-Control: max-age=31536000, immutable(配合文件指纹)
图片/字体等媒体资源长时间缓存 + 内容哈希命名
API 接口数据根据业务设置合理 max-age,必要时禁用缓存

💡 小技巧:使用 Webpack/Vite 构建时,通过 [contenthash] 实现静态资源长期缓存。


六、如何调试缓存?

打开 Chrome DevTools → Network 面板:

  • 查看状态码:
    • 200(from cache):强缓存命中
    • 304:协商缓存生效
    • 200(常规):重新下载资源
  • 检查 Response Headers 中的 Cache-ControlETag 等字段

七、总结

对比项强缓存协商缓存
是否发请求❌ 不发✅ 发
状态码200 (from cache)304200
判断依据Cache-Control / ExpiresETag / Last-Modified
优先级更高强缓存失效后启用
性能表现最优次优(有网络通信)

最佳实践
合理设置 Cache-Control 实现长期缓存,搭配 ETag 提供精准更新检测,既能提升性能,又能保证内容实时性。