强缓存和协商缓存是浏览器缓存机制的两种核心方式,用于提升网页加载速度、减少服务器压力。
一、什么是强缓存(Strong Cache)
定义:
强缓存指的是:浏览器在 不向服务器发送请求 的前提下,直接从缓存中读取资源。
关键响应头:
响应头字段 | 说明 |
---|---|
Cache-Control |
现代浏览器首选,控制资源缓存的方式和时长(优先级更高) |
Expires |
HTTP/1.0 使用,指定资源过期的具体时间(绝对时间) |
示例:
Cache-Control: max-age=3600
表示该资源在被请求后的 1小时内有效,这段时间内,浏览器 不会再向服务器发请求,直接从缓存中取资源。
应用场景:
- 图片、CSS、JS 等静态资源(版本更新频率不高)
- 加载速度要求高的页面资源
二、什么是协商缓存(Negotiated Cache / Conditional Cache)
定义:
当资源过期时(强缓存失效),浏览器会向服务器发出请求,但带上缓存标识。服务器判断资源是否更新:
- 未更新 → 返回 304 Not Modified,使用本地缓存;
- 已更新 → 返回新的资源(200 OK 和新内容)。
关键字段:
请求头:
请求头字段 | 说明 |
---|---|
If-Modified-Since |
上次服务器响应中的 Last-Modified 时间 |
If-None-Match |
上次响应的 ETag 值(资源内容的唯一标识) |
响应头:
响应头字段 | 说明 |
---|---|
Last-Modified |
文件的最后修改时间 |
ETag |
文件的唯一标识(由服务器生成,优先级更高) |
示例流程:
- 首次请求资源,响应头带:
ETag: "abc123"
- 下一次请求资源,请求头带:
If-None-Match: "abc123"
- 如果资源未变,服务器返回:
HTTP/1.1 304 Not Modified
浏览器用本地缓存。
应用场景:
- 资源可能会更新但频率较低
- 数据接口请求(如分页数据)
- JS、CSS 等有版本控制的资源
三、强缓存与协商缓存的优先级
浏览器会按以下顺序判断是否使用缓存:
是否命中强缓存(如 Cache-Control)
是 → 直接用缓存,不发请求
否 → 进入协商缓存判断
是否命中协商缓存(如 If-None-Match)
是 → 返回 304,不下载资源,只发轻量请求
否 → 返回 200,下载新资源
四、应用策略推荐
类型 | 缓存策略建议 |
---|---|
静态资源 | 强缓存(设置长时间 max-age + 加 hash) |
动态请求数据 | 协商缓存(启用 ETag / Last-Modified ) |
HTML 文件 | 不建议强缓存,协商缓存 + 控制更新频率 |
CDN 加速资源 | 一般由 CDN 自动加 Cache-Control 策略 |
前端打包时推荐:
使用 Webpack/Vite 的 hash 文件名策略:
app.73ddfa.js
修改代码自动改变文件名,从而避免旧缓存(缓存穿透问题)。
五、如何查看缓存策略(以 Chrome 为例)
打开 DevTools → Network
刷新页面(建议勾选 “Disable cache” 测试后再取消)
查看资源请求状态:
- from memory cache:内存缓存
- from disk cache:磁盘缓存
- 200:正常请求
- 304:协商缓存命中
六、总结对比表
特点 | 强缓存 | 协商缓存 |
---|---|---|
是否发送请求 | ❌不发送 | ✅发送 |
状态码 | 无(直接读取缓存) | 304 Not Modified |
浏览器是否使用本地缓存 | ✅ | ✅ |
触发条件 | Expires /Cache-Control |
ETag /Last-Modified |
性能 | 更好 | 较好 |
七、内存缓存 vs 磁盘缓存 的区别
类型 | 说明 |
---|---|
内存缓存 | 缓存在浏览器的内存中,生命周期短,标签页关闭即释放 |
磁盘缓存 | 缓存在硬盘中,生命周期长,页面刷新、浏览器重启后仍可使用 |
八、是否使用磁盘/内存缓存的判断依据
浏览器会根据以下因素决定资源是否放入 内存缓存 还是 磁盘缓存:
存入内存缓存的典型条件:
小文件(如小图标、小脚本)
生命周期短、频繁访问的资源
页面首次加载过程中的资源
当前标签页使用的资源
存入磁盘缓存的典型条件:
体积较大的资源(如视频、图片、JS/CSS)
设置了较长过期时间的资源(Cache-Control: max-age=xxx)
资源用于多个页面/标签页复用
非私密资源(非 Cache-Control: no-store)
九、与强缓存/协商缓存的关系
强缓存会触发磁盘或内存缓存:
浏览器决定使用强缓存后,会尝试从内存或磁盘读取缓存文件
哪个缓存命中取决于:缓存位置 + 缓存是否仍在有效期
协商缓存则总是会发请求,所以它不影响“是否存在哪种缓存”,但可能依赖磁盘缓存提供的文件副本以减少加载成本
示例:
Cache-Control: no-store
浏览器完全不会缓存(内存或磁盘都不会)
Cache-Control: public, max-age=86400
强缓存 1 天,浏览器倾向于将其 存入磁盘
总结
问题 | 答案 |
---|---|
强缓存/协商缓存是否决定内存/磁盘缓存? | ❌ 不直接决定,但会影响浏览器是否使用缓存 |
什么决定资源存到哪里? | ✅ 由浏览器内部策略决定(文件大小、访问频率、生命周期等) |
是否可以控制资源不被缓存? | ✅ 使用 Cache-Control: no-store 或 Pragma: no-cache |