网络缓存控制指南:强缓存与协商缓存

适用场景:Web性能优化、静态资源管理、API响应优化

缓存基础概念

什么是缓存?

浏览器或服务器通过缓存机制减少重复请求,提升加载速度。缓存分为 强缓存(直接使用本地资源)和 协商缓存(验证资源是否更新)。

强缓存配置

1. 定义与原理

  • 直接命中:浏览器无需与服务器通信,直接使用本地缓存资源。
  • 控制方式:通过 Cache-ControlExpires 响应头设置。

2. 关键响应头

响应头说明
Cache-Control: max-age=3600相对时间(1小时),优先级高于 Expires(推荐使用)。
Expires: Thu, 31 Dec 2030 23:59:59 GMT绝对时间(依赖客户端时钟,可能误差)。

3. Nginx 配置示例

1
2
3
4
5
# 配置静态资源强缓存(1年有效期)
location ~* \.(jpg|png|css|js)$ {
expires 1y; # 绝对时间
add_header Cache-Control "public, max-age=31536000"; # 相对时间(31536000秒=1年)
}

4. 行为流程

  1. 首次请求:服务器返回资源 + 缓存头。
  2. 后续请求:浏览器直接读取本地缓存(状态码 200 (from disk cache))。

5. 适用场景

  • 静态资源:图片、CSS、JS、字体文件等长期不变的资源。
  • 优化目标:完全避免网络请求,降低服务器负载。

协商缓存配置

1. 定义与原理

  • 验证更新:浏览器每次请求时携带缓存标识,服务器验证后返回 304 Not Modified 或新资源。
  • 控制方式:通过 Last-ModifiedETag 响应头。

2. 关键响应头

响应头说明
Last-Modified: Wed, 21 Oct 2023 07:28:00 GMT资源最后修改时间(精度为秒)。
ETag: "5d8c72a5-264"资源唯一标识(哈希值或版本号,精度更高)。

3. Nginx 配置示例

1
2
3
4
5
# 启用协商缓存(默认已支持)
location / {
etag on; # 启用ETag
add_header Last-Modified ""; # 显式输出Last-Modified
}

4. 行为流程

  1. 首次请求:服务器返回资源 + Last-Modified/ETag
  2. 后续请求:浏览器携带 If-Modified-SinceIf-None-Match 验证。
  3. 响应结果
    • 未修改:返回 304 Not Modified,使用本地缓存。
    • 已修改:返回 200 OK 和新资源。

5. 适用场景

  • 动态资源:HTML页面、API响应等可能频繁更新的内容。
  • 优化目标:减少全量传输,仅在必要时更新资源。

强缓存与协商缓存对比

特性强缓存协商缓存
通信成本无网络请求需发送请求验证
响应状态码200 (from disk cache)304 Not Modified
优先级优先于协商缓存强缓存过期后触发
适用资源长期不变的静态资源频繁更新的动态资源

Nginx 最佳实践

1. 混合配置示例

1
2
3
4
5
# 强缓存 1 小时,过期后触发协商缓存
location / {
add_header Cache-Control "public, max-age=3600";
etag on;
}

2. 按文件类型区分策略

1
2
3
4
5
6
7
8
9
10
# 图片、字体等强缓存
location ~* \.(jpg|png|gif|woff2)$ {
expires 1y;
add_header Cache-Control "public, max-age=31536000";
}

# HTML文件禁用强缓存(强制协商)
location ~* \.html$ {
add_header Cache-Control "no-cache, must-revalidate";
}

3. 解决缓存更新问题

  • 强缓存:通过 文件名哈希(如 main.abcd1234.js)强制浏览器加载新版本。
  • 协商缓存:更新 ETagLast-Modified 值触发更新。

调试工具与步骤

1. 浏览器开发者工具

  • Network 标签:
    • 查看 Status 列:200 (from disk cache)(强缓存命中)或 304(协商缓存命中)。
    • 检查 Headers 标签中的 Cache-ControlETag 等响应头。

2. 命令行调试

1
2
# 查看资源响应头
curl -I http://example.com/resource.js

注意事项

  1. 强缓存风险

    • 避免长期强缓存:若资源更新,需通过版本号或哈希名强制更新。
    • Expires 时间依赖客户端时钟:建议优先使用 Cache-Control
  2. 协商缓存优化

    • ETag 优先级:若同时存在 ETagLast-Modified,服务器优先验证 ETag
  3. 安全配置

    • 对敏感资源(如用户数据)禁用缓存:
    1
    add_header Cache-Control "no-store, private";

常见问题解答

Q1:如何强制浏览器更新强缓存资源?

  • 修改文件名(如 main.jsmain_v2.js)或添加查询参数(如 ?v=2)。

Q2:为什么协商缓存返回 200 而非 304?

  • 服务器检测到资源已修改,需返回新内容。检查 Last-ModifiedETag 是否变化。

Q3:如何调试缓存配置?

  • 清除浏览器缓存后重新加载,观察 Network 标签中的响应头和状态码。

相关资源