浏览器缓存策略是提升网页加载速度、减少服务器负载的关键机制。它通过将资源存储在本地,避免重复下载。以下是浏览器缓存的详细工作机制和策略:
一、缓存类型
-
强缓存(无需服务器验证)
- 浏览器直接检查本地缓存,未过期则直接使用,不发送请求。
- 通过以下响应头控制:
Cache-Control(HTTP/1.1)max-age=3600:资源有效期(秒)。no-cache:强制协商缓存。no-store:禁止缓存。public:允许代理/CDN缓存。private:仅浏览器可缓存。
Expires(HTTP/1.0,已被淘汰)
指定过期时间(如Expires: Wed, 21 Oct 2025 07:28:00 GMT),依赖客户端时间可能不准。
-
协商缓存(需服务器验证)
- 强缓存失效后,浏览器携带验证字段向服务器询问资源是否修改。
- 通过以下头字段控制:
Last-Modified(服务器返回) +If-Modified-Since(浏览器发送)
基于时间戳验证,精度为秒级,可能因文件内容未变但时间戳更新导致失效。ETag(服务器返回) +If-None-Match(浏览器发送)
基于文件哈希值(如"5d8c72a5edda8"),更精确,但计算开销大。
二、缓存位置
- Memory Cache
内存缓存,快速但生命周期短(随进程关闭释放),适合小文件或高频资源。 - Disk Cache
磁盘缓存,持久化存储,适合大文件或低频资源。 - Service Worker Cache
通过Service Worker拦截请求,实现离线缓存(PWA核心技术)。 - Push Cache
HTTP/2服务器推送的缓存,会话级存储,优先级最低。
三、关键HTTP头字段
| 头字段 | 方向 | 作用 |
|---|---|---|
Cache-Control | 响应/请求 | 控制缓存行为(优先级最高) |
Expires | 响应 | 过期时间(HTTP/1.0) |
Last-Modified | 响应 | 资源最后修改时间 |
If-Modified-Since | 请求 | 携带上次的Last-Modified值 |
ETag | 响应 | 资源唯一标识 |
If-None-Match | 请求 | 携带上次的ETag值 |
Vary | 响应 | 指定缓存依据的请求头(如Accept-Encoding) |
四、缓存流程示例
-
首次请求
GET /script.js服务器返回:
HTTP/1.1 200 OK Cache-Control: public, max-age=3600 ETag: "abc123" Last-Modified: Wed, 01 Jun 2025 10:00:00 GMT -
再次请求(强缓存有效)
浏览器直接从本地缓存读取,不发送请求。 -
强缓存过期后
浏览器发送验证请求:GET /script.js If-None-Match: "abc123" If-Modified-Since: Wed, 01 Jun 2025 10:00:00 GMT若未修改,服务器返回304:
HTTP/1.1 304 Not Modified
五、最佳实践
-
静态资源(JS/CSS/图片)
- 设置长缓存:
Cache-Control: public, max-age=31536000(1年)。 - 通过文件名哈希(如
app.a1b2c3.js)实现内容更新时URL变化,强制重新下载。
- 设置长缓存:
-
HTML文件
- 使用
Cache-Control: no-cache或短缓存,确保及时获取更新。
- 使用
-
API请求
- 敏感数据用
no-store禁止缓存。 - 频繁变动的数据用
no-cache或max-age=0强制验证。
- 敏感数据用
六、调试工具
- Chrome DevTools
- Network面板:查看请求的
Size列(from memory/disk cache表示命中缓存)。 - 勾选
Disable cache模拟首次访问。
- Network面板:查看请求的
- curl命令
curl -v http://example.com/resource -H 'Cache-Control: no-cache'
七、常见问题
- 缓存污染:错误的
Cache-Control设置导致用户获取旧版本。 - CDN缓存:需同步配置
Cache-Control和Vary头。 - 隐私模式:浏览器默认不持久化缓存。
通过合理配置缓存策略,可显著提升用户体验并降低服务器压力。