页面缓存命中率无法被前端JavaScript直接监测,但可通过Network面板状态码、Size字段、TTFB、X-Cache响应头及Performance API的transferSize等间接信号准确判断缓存是否生效及其对首屏性能的影响。

页面缓存命中率本身无法被前端 JavaScript 直接监测——浏览器不提供 API 返回“本次 HTML 是否命中强缓存”或“CSS 是否从磁盘缓存加载”。但你可以通过间接指标和可观测信号,准确判断缓存是否生效、是否拖慢性能,并定位它对首屏时间、TTFB、资源加载节奏的实际影响。
看 Network 面板里的关键信号
这是最直接、最可靠的监控方式。打开 Chrome DevTools → Network 标签页,刷新页面,重点关注 index.html 和核心静态资源(如 main.a1b2c3.js、app.css):
- Status 显示 “(from cache)” 或 “(from disk cache)”:说明该资源未发网络请求,命中强缓存;若显示 “200” 且 Size 列为实际字节数(非 “(from cache)”),说明未命中,走了网络
- TTFB(Time to First Byte)极低(如 :大概率命中了协商缓存(304),服务器快速返回了验证通过响应
- HTML 请求耗时长、TTFB 高(> 200ms)、Status 是 “200” 且 Size 较大:缓存完全失效,每次都在重新下载 HTML —— 这是性能隐患的明确信号
-
注意 X-Cache 或 X-CDN-Cache 响应头:如 Cloudflare 返回
x-cache: HIT,阿里云返回x-cdn-cache: HIT,说明 CDN 层也命中了,叠加效应明显
用 Navigation Timing API 捕获真实加载行为
借助 window.performance.getEntriesByType("navigation") 可拿到本次导航的完整时序数据,重点看:
-
transferSize:实际从网络接收的字节数。若 HTML 的
transferSize === 0,基本可确认命中了本地强缓存(注意:某些浏览器在协商缓存 304 场景下也可能为 0,需结合 status 判断) - encodedBodySize:响应体压缩后大小。若远小于首次加载值,且 transferSize 小,说明复用的是缓存副本
- fetchStart → responseStart 差值:反映资源开始接收响应的时间点。该间隔显著缩短,通常是缓存生效的表现
服务端日志 + 缓存头联动分析
前端监控有盲区,必须和服务端协同:
立即学习“前端免费学习笔记(深入)”;
- 在 Nginx / Apache 日志中开启
$upstream_http_cache_status(Nginx)或对应缓存状态字段,记录每次 HTML 请求的缓存结果(MISS / HIT / EXPIRED / BYPASS) - 将该状态与前端上报的
navigationTiming数据(如 domContentLoadedEventEnd、loadEventEnd)做关联分析:当服务端标记为 HIT 但前端 load 时间仍很长,问题可能出在 JS 执行或渲染阶段,而非缓存本身 - 特别关注
Cache-Control响应头是否被 CDN 覆盖或篡改——很多性能问题根源在于 CDN 控制台配置覆盖了源站 header,导致本该 no-cache 的 HTML 被 CDN 强制缓存 10 分钟
缓存失效引发的典型性能劣化模式
命中率低 ≠ 性能差,但“错配”的缓存策略会稳定拉低体验:
- HTML 设了 max-age=3600,但没配 ETag:用户第二次访问仍发完整请求(TTFB 高 + transferSize 大),等于白设缓存
- JS/CSS 用了哈希命名,却没加 immutable:浏览器每次都要发 If-None-Match 验证,多一次 RTT,首屏 JS 加载延迟 80–200ms
- CDN 缓存了 HTML,但 JS 文件名没哈希:CDN 返回新 HTML,浏览器却还在用旧缓存的 JS,导致功能异常或白屏,用户被迫硬刷
- Service Worker 拦截 HTML 但未正确处理 fetch 失败降级:离线时 fallback 逻辑缺失,直接报错而非展示缓存页



















