performance.getentriesbytype('resource') 返回空数组主因是资源未被浏览器记录:沙箱iframe缺allow-performance权限、跨域资源缺失timing-allow-origin头、或调用时机过早;应改用buffered:true的performanceobserver实时捕获。

performance.getEntriesByType('resource') 为什么总返回空数组
不是代码写错了,而是资源条目根本没被浏览器记录——沙箱环境(如 iframe sandbox)、跨域资源缺失 Timing-Allow-Origin 头、或监听时机太早,都会导致返回空数组。
常见错误现象:
-
performance.getEntriesByType('resource')在window.addEventListener('load', ...)里调用,但依然为空 - 微前端子应用里完全拿不到任何资源条目
- 动态插入的
<script></script>或<img>在回调里查不到对应 entry
实操建议:
- 确认 iframe 是否带
sandbox="allow-scripts allow-performance"——allow-performance是 Chrome 98+ 才支持的必需权限,Firefox 当前不支持 - 检查第三方资源响应头是否含
Timing-Allow-Origin: https://your-domain.com(不能用*,沙箱下无效) - 别依赖一次性取数,改用
PerformanceObserver+buffered: true,确保历史条目不丢失
如何用 PerformanceObserver 捕获所有资源(含动态插入)
轮询 getEntriesByType 或等 load 事件,对懒加载、fetch 注入、运行时创建的 <link> 都不可靠。真正能覆盖全场景的是 PerformanceObserver。
关键点:
-
buffered: true必须设,否则只收到 observer 创建之后的新条目,漏掉页面已加载完的资源 - 回调中过滤
entry.entryType === 'resource'即可,无需额外判断是否完成加载 - 沙箱 iframe 内的 observer 只能看到自身上下文资源,看不到父页面或同级 iframe 的
最小可用示例:
const observer = new PerformanceObserver(list => {
list.getEntries().forEach(entry => {
if (entry.entryType === 'resource') {
console.log(entry.name, entry.duration);
}
});
});
observer.observe({ entryTypes: ['resource'], buffered: true });
分阶段看字段:DNS、TCP、TTFB、下载哪个环节拖慢了资源
只看 duration 容易误判。真实瓶颈往往藏在中间阶段,比如 DNS 查询慢、TLS 握手卡住、或后端响应迟滞。
常用差值字段与阈值参考(单位 ms):
- DNS 慢:
entry.domainLookupEnd - entry.domainLookupStart > 100→ 考虑<link rel="preconnect"> - TCP/TLS 卡住:
entry.connectEnd - entry.connectStart > 200→ iOS 对 OCSP stapling 敏感,HTTPS 配置需检查 - TTFB 高:
entry.responseStart - entry.requestStart > 500→ 后端渲染、CDN 回源、数据库查询都可能拖累 - 下载慢:
entry.responseEnd - entry.responseStart明显偏高 → 查entry.transferSize,未压缩或带宽不足 - 字段为 0:
entry.domainLookupStart === 0表示走缓存,此时其他网络字段也无效,不用分析
第三方脚本识别和瓶颈定位为什么不能只靠 initiatorType
initiatorType === 'script' 只能捕获直接通过 <script src></script> 加载的脚本。大量埋点 SDK、A/B 测试工具、监控 agent 是通过 fetch 拉取后 eval 或 Function 执行的,它们不会出现在 script 类型里。
更可靠的识别方式:
- 用 URL 关键词匹配:
entry.name.includes('google-analytics.com')、entry.name.includes('gtm.js') - 排除自家域名:
!entry.name.includes(window.location.hostname) - 聚合类服务按路径识别:
entry.name.includes('/bundle.') || entry.name.includes('sentry')
注意:跨域第三方若没配 Timing-Allow-Origin,domainLookupStart、connectStart 等字段会是 0,这时 duration 和 responseStart - requestStart 是唯一可信字段。
沙箱里尤其容易忽略服务端响应头配置,而它直接决定你能不能看到真实网络耗时——不是数据丢了,是浏览器主动过滤了。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











