可通过PerformanceResourceTiming的transferSize等字段准确推断缓存命中:transferSize为0且decodedBodySize>0表示强缓存命中,transferSize>0且状态码304表示协商缓存生效,结合X-Cache响应头可识别CDN或Service Worker缓存,统计命中率并关联Navigation Timing验证性能收益。
不能直接读取“缓存命中”布尔值,但可以通过 PerformanceResourceTiming 接口中的 transferSize 和 decodedBodySize 等字段,结合响应头与加载行为,准确推断资源是否命中浏览器缓存。
transferSize 表示实际从网络接收的字节数。这是最可靠的核心指标:
transferSize === 0 且 decodedBodySize > 0,基本可确认该资源来自内存或磁盘缓存(强缓存命中)transferSize > 0 但远小于首次加载值,且响应状态码为 304 Not Modified,说明协商缓存生效transferSize 接近 decodedBodySize 且状态码为 200,则未命中缓存,完整下载浏览器不暴露缓存层级,但服务端可通过响应头传递缓存状态:
response.headers.set('X-Cache-Hit', 'true')
x-cache: HIT,阿里云返回 x-cdn-cache: HIT
performance.getEntriesByType('resource') 获取条目后,需配合 fetch() 或 Response.clone().headers(仅限同源或 CORS 允许)读取响应头在页面加载完成后(如 window.addEventListener('load', ...)),遍历所有资源条目:
performance.getEntriesByType('resource').length
entry.transferSize === 0 && entry.decodedBodySize > 0 的条目数(hitCount / totalCount * 100).toFixed(2) + '%'
光看命中率不够,要验证它是否带来实际提速:
performance.getEntriesByType('navigation')[0] 获取首屏关键时序domContentLoadedEventEnd 或 loadEventEnd 在缓存命中/未命中场景下的差异entry.name 对应的条目 transferSize === 0,再检查其 renderTime 是否显著提前(通常早 200–800ms)