怎么判断图片是命中强缓存还是协商缓存?
判断图片是否命中强缓存或协商缓存,主要通过浏览器开发者工具的Network面板查看资源加载状态、分析HTTP响应头字段以及观察资源加载特征来实现。
一、核心判断方法
1. 浏览器Network面板状态(最直观有效)
强缓存命中:
- Size列显示
from disk cache或from memory cache - Status列显示
200 (from disk cache)或类似表述 - 无网络请求:资源直接从本地缓存读取,不向服务器发送请求
- 加载时间极短:通常接近0ms,Waterfall图表中显示为瞬间完成
协商缓存命中:
- Size列显示
304(或很小的字节数) - Status列显示
304 Not Modified - 有网络请求:浏览器向服务器发送验证请求,但服务器返回304状态码
- 加载时间稍长:因有验证请求过程,通常比强缓存稍慢
2. HTTP响应头分析(关键证据)
强缓存特征:
- 响应头包含
Cache-Control: max-age=xxx(如max-age=31536000) - 或包含
Expires(绝对时间,如Expires: Wed, 11 May 2018 07:20:00 GMT) - 无ETag或Last-Modified验证过程:强缓存有效期内不进行服务器验证
协商缓存特征:
- 响应头包含
ETag: "xxx"或Last-Modified: <http-date> - 请求头包含
If-None-Match: "xxx"或If-Modified-Since: <http-date> - 服务器返回
304 Not Modified,表示资源未变化
3. 资源加载特征对比
| 特征 | 强缓存命中 | 协商缓存命中 |
|---|---|---|
| 网络请求 | ❌ 无请求 | ✅ 有验证请求 |
| 响应状态码 | 200 (from cache) | 304 Not Modified |
| 资源传输大小 | 0字节(直接读取本地) | 极小(仅响应头) |
| 加载时间 | 极短(<50ms) | 稍长(有RTT延迟) |
| 缓存验证 | 无需验证 | 需服务器验证 |
二、实用操作步骤
1. 浏览器开发者工具验证(推荐方法)
- 打开Chrome浏览器 → 按
F12或Ctrl+Shift+I打开开发者工具 - 切换到Network面板 → 勾选"Preserve log"和"Disable cache"(测试前)
- 首次访问:刷新页面,记录图片资源的初始加载情况
- 再次访问:刷新页面(不勾选"Disable cache")
- 查看目标图片资源的:
- Size列:是否显示
from disk cache(强缓存)或304(协商缓存) - Status列:是否为
200 (from disk cache)(强缓存)或304 Not Modified(协商缓存) - Response Headers:检查
Cache-Control、ETag、Last-Modified等关键字段
- Size列:是否显示
2. 命令行工具验证
# 查看图片资源响应头
curl -I https://your-website.com/path/to/image.jpg
# 验证缓存效果(对比首次和后续请求)
curl -o devnull -s -w "首次请求: %{time_total}\n" https://your-website.com/image.jpg
curl -o devnull -s -w "后续请求: %{time_total}\n" https://your-website.com/image.jpg
- 强缓存命中:后续请求时间接近0秒
- 协商缓存命中:后续请求时间有明显但较小的延迟(仅验证请求)
3. JavaScript性能API验证
// 获取所有资源性能数据
const resources = performance.getEntriesByType('resource');
// 验证图片缓存类型
resources.forEach(resource => {
if (resource.name.endsWith('.jpg') ||
resource.name.endsWith('.png')) {
// 强缓存命中判断:无网络传输但资源存在
const isStrongCache = resource.transferSize === 0 && resource.decodedBodySize > 0;
// 协商缓存命中判断:有验证请求但无资源下载
const isNegotiatedCache = resource.transferSize > 0 &&
resource.transferSize < 100 &&
resource.decodedBodySize > 0;
console.log(`图片 ${resource.name} 缓存类型: ${isStrongCache ? '强缓存' : (isNegotiatedCache ? '协商缓存' : '无缓存')}`);
}
});
三、常见问题与解决方案
1. 误判情况排查
问题:Cache-Control设置长缓存但实际未命中
- 原因:文件名未带哈希,HTML引用旧资源
- 解决方案:采用
main.abc123.js格式的文件名,设置Cache-Control: max-age=31536000, immutable
问题:no-cache被误解为"不缓存"
- 原因:
no-cache实际是"缓存前必须向服务器确认" - 解决方案:需要完全不缓存时使用
no-store,而非no-cache
2. 缓存策略优化建议
静态资源(图片、CSS、JS):
- 推荐:设置长强缓存 + 文件名哈希(如
Cache-Control: max-age=31536000, immutable) - 避免:对未指纹化的资源设置长缓存,导致更新困难
HTML文件:
- 推荐:设置短缓存或协商缓存(如
Cache-Control: no-cache) - 原因:HTML是入口文件,需确保用户获取最新版本
3. 专业测试技巧
- 强制刷新测试:按
Ctrl+F5触发硬刷新,观察是否从服务器获取新资源 - 清除缓存测试:使用浏览器"Clear browsing data"功能清除缓存后测试
- 多设备测试:不同设备/浏览器对缓存处理可能有差异
- CDN协同验证:检查CDN配置是否与源站缓存策略一致
四、最佳实践总结
- 优先检查响应头:
Cache-Control和Expires决定强缓存,ETag和Last-Modified决定协商缓存 - 结合Network面板数据:综合判断Size、Status和Waterfall数据
- 区分缓存类型:
- 强缓存:无网络请求,直接读取本地缓存,适用于长期不变的资源
- 协商缓存:有验证请求,适用于可能更新但频率较低的资源
- 量化评估:强缓存命中率>95%为优秀,协商缓存命中率>80%为良好
- 持续监控:定期检查缓存命中情况,优化CDN和源站配置
重要提示:缓存策略应根据资源特性定制,静态资源优先使用强缓存(配合文件名哈希),动态内容使用协商缓存。通过合理配置,可使图片等静态资源加载速度提升30%-50%,显著改善用户体验。若发现缓存命中率低,建议检查CDN缓存策略、资源TTL设置以及源站响应头是否正确。