直接调用performance.getEntriesByType('resource')可获取所有已完成加载的资源条目,但需先过滤无效数据(如domainLookupStart为0、跨域缺Timing-Allow-Origin头、强缓存导致duration为0),再通过差值计算DNS、TCP、SSL、TTFB、下载等阶段耗时,最后结合业务聚焦上报超时或关键资源。

直接调用 performance.getEntriesByType('resource') 就能拿到所有已完成加载的资源条目,但要真正用于性能分析,得先过滤有效数据、再拆解关键阶段耗时、最后结合业务做判断。
筛选出你关心的资源
返回的是一个数组,每项是 PerformanceResourceTiming 实例。常用筛选方式有三种:
- 按类型:用
entry.initiatorType区分,比如'script'(JS)、'img'(图片)、'link'(CSS) - 按 URL 后缀:比如
entry.name.endsWith('.js')或.css、.webp - 按 MIME 类型:比如
entry.mimeType === 'application/javascript',适合区分动态注入的模块
提取各阶段真实耗时
每个条目提供微秒级时间戳,需通过差值计算实际耗时。注意不是所有字段都有值,要加判断:
使用约定式提交(Conventional Commits)生成标准化的 Git 提交信息。适用于以下场景: (1) 暂存更改时需要提交信息; (2) 审查 diff 时希望获得结构化摘要; (3) 编写 PR 描述或变更日志(changelog)条目; (4) 用户明确要求“为本次更改编写提交信息”。 该功能会分析已暂存/未暂存的 diff,并生成按类型(type)划分范围的提交信息。
- DNS 查询:仅当
entry.domainLookupStart > 0时,才用entry.domainLookupEnd - entry.domainLookupStart - TCP 连接:用
entry.connectEnd - entry.connectStart,若为 0 说明复用连接 - SSL 握手:只在 HTTPS 下有效,且需
entry.secureConnectionStart > 0,再算entry.connectEnd - entry.secureConnectionStart - TTFB:即首字节时间,
entry.responseStart - entry.requestStart,这是后端响应快慢的关键指标 - 下载耗时:
entry.responseEnd - entry.responseStart,反映网络带宽和资源体积影响 - 总耗时:
entry.duration,但强缓存(304 / from memory cache)下可能为 0,不能直接用于瓶颈归因
避开常见无效数据陷阱
不加过滤容易误判。以下情况建议跳过或单独标记:
-
entry.domainLookupStart === 0:DNS 被本地缓存或 HTTP/2 复用,无法计算 DNS 时间 - 跨域资源没有 timing 数据:检查服务端是否返回了
Timing-Allow-Origin: *响应头 -
entry.duration === 0:大概率是强缓存命中,此时 TTFB 和下载时间也无意义,不应计入网络问题统计 - 资源在
DOMContentLoaded之后才出现:比如动态插入的 script,建议在该事件回调里第一时间采集,避免漏掉
轻量上报与业务结合
别全量上报,优先聚焦问题:
- 只上报超时资源:例如 TTFB > 800ms、总耗时 > 5s,或下载耗时异常高(如 > 3s 的图片)
- 带上上下文:资源类型、URL、页面路径、用户设备类型(可从
navigator.userAgent粗略判断) - 用
navigator.sendBeacon()上报,不阻塞页面卸载或跳转 - 对首屏关键 JS/CSS 单独打标,比如在
<script></script>标签上加data-critical属性,采集时一并提取,便于定位首屏阻塞点


















