getEntriesByType('resource') 是 PerformanceObserver 提供的底层 API,用于捕获 script、style、img 等资源的完整加载性能数据,结合使用状态、重复请求、加载时机和资源开销等维度可系统识别冗余加载。

getEntriesByType('resource') 是 PerformanceObserver API 提供的底层能力,可捕获页面中所有已加载的资源(如 script、style、img、font、fetch 等)的完整性能数据。它本身不直接标记“冗余”,但结合资源加载时机、使用状态、复用情况和网络/渲染上下文,就能系统识别冗余加载——比如预加载了但从未执行的 JS、CSS 中未使用的规则对应的实际文件、重复请求的相同字体、或首屏无需却提前 fetch 的数据。
明确“冗余”的判定维度
自动化分析前需定义什么是“冗余”,常见有效维度包括:
-
未被实际使用:资源已加载,但 DOM 中无对应节点(如
加载了 JS 却没<script></script>执行;或 CSS 文件被加载但其规则在 DevTools 的 Coverage 工具中显示 90% 未命中) - 重复加载:同一 URL(忽略 query 参数差异)在 performance entries 中出现 ≥2 次,且非因缓存失效(status=200 而非 304/200 from disk cache)
-
非必要时机加载:资源 initiatorType 为
navigation或parser,但startTime (首屏关键路径内),而后续检测发现该资源对首屏渲染/交互无贡献(例如某分析 SDK 的 JS 在 DOMContentLoaded 前就加载,但所有上报逻辑都在 5s 后才触发) -
高开销低价值:资源
transferSize > 100KB且duration (极快完成,大概率被 abort 或未执行),或renderBlocking = true(通过isLinkPreload+as类型推断)但未参与样式计算
基础采集与结构化处理
先稳定获取并清洗 resource entries:
- 使用
PerformanceObserver监听'resource',务必在页面最顶部(如 内联脚本)启动,避免漏掉早期资源 - 调用
getEntriesByType('resource')获取全量条目后,过滤掉initiatorType === 'xmlhttprequest'(若只关注静态资源)或保留并打标(便于区分数据请求) - 对每个 entry 补充可判定字段:
•isPreloaded:检查initiatorType === 'preload'
•isBlocking:当name以.css结尾且initiatorType !== 'xmlhttprequest',视为潜在阻塞
•urlHash:取 URL 去参哈希(如new URL(e.name).origin + new URL(e.name).pathname),用于去重比对
典型冗余模式与检测代码片段
以下逻辑可在采集后直接运行(例如在 load 事件后):
-
重复请求检测:
const dupes = entries.reduce((map, e) => {<br> const key = e.urlHash;<br> map[key] = (map[key] || 0) + 1;<br> return map;<br> }, {});<br> const redundantLoads = Object.entries(dupes).filter(([, count]) => count > 1).map(([url]) => entries.filter(e => e.urlHash === url)); -
预加载未使用检测:
const preloaded = entries.filter(e => e.initiatorType === 'preload');<br> const loadedScripts = entries.filter(e => e.name.endsWith('.js') && e.initiatorType !== 'preload');<br> // 检查是否有 preload 的 JS URL 完全未出现在后续 script 加载中<br> const unusedPreloads = preloaded.filter(p => !loadedScripts.some(s => s.name === p.name)); -
大体积低耗时资源预警:
const suspicious = entries.filter(e => e.transferSize > 1024 * 100 && e.duration // 进一步排除 favicon.ico、manifest.json 等合理小耗时资源
联动其他 API 提升准确率
单靠 resource entries 有局限,建议组合使用:
- 搭配
document.styleSheets和getComputedStyle()验证 CSS 是否真被应用(尤其动态插入的 style 标签) - 用
performance.getEntriesByType('navigation')[0].serverTiming(如有)交叉验证后端是否主动推送了冗余资源 - 监听
document.addEventListener('DOMContentLoaded', ...)后遍历document.querySelectorAll('link[rel="preload"]'),比对是否所有 preload 都已在 resource entries 中出现且未被 abort(entry.encodedBodySize === 0可能表示中断)










