第三方脚本性能瓶颈在于DNS、连接或传输阶段而非执行本身,应通过PerformanceObserver实时捕获resource条目,结合URL关键词精准识别,并重点分析domainLookupEnd-domainLookupStart、connectEnd-connectStart、responseEnd-requestStart等字段定位卡点。
直接用
提取所有资源记录,再按 URL 或类型筛选出第三方脚本,就能看到它们真实的 DNS、连接、请求和执行耗时——关键不是“有没有加载”,而是“每一步卡在哪”。
抓取完整资源时间线
第三方脚本是否被缓存、是否跨域、是否触发重定向,都会影响字段完整性。必须在页面
完全加载后
(比如
)调用,否则很多条目还没完成,返回空数组或缺失关键字段。
推荐写法:
监听
的
,实时捕获每个脚本的加载完成事件
避免只依赖首次调用
,尤其在 SPA 中,动态插入的脚本需单独观察
对 CDN 域名(如
)检查
和
是否为 0:若为 0,大概率是跨域且服务端没配
,网络阶段数据不可信
精准识别第三方脚本
不能只靠
,因为有些埋点 SDK 是通过
或
动态拉取并
执行的,不会出现在 script 类型里。
立即学习
“
前端免费学习笔记(深入)
”;
使用HTML,CSS,JavaScript开发Android应用程序 英文文字pdf版附源文件
如果你了解HTML,CSS和JavaScript,您已经拥有所需的工具开发Android应用程序。本动手本书展示了如何使用这些开源web标准设计和建造,可适应任何Android设备的应用程序 - 无需使用Java。您将学习如何创建一个在您选择的平台的Android友好的网络应用程序,然后转换与自由PhoneGap框架到一个原生的Android应用程序。了解为什么设备无关的移动应用是未来的潮流,并开始构建应用程序,提供更
下载
更可靠的方式是结合 URL 特征过滤:
用
、
等明确域名关键词匹配
排除自家域名:
对聚合类服务(如 Sentry、Bugsnag),可匹配路径关键词:
看懂关键耗时字段含义
第三方脚本慢,往往不是代码本身执行慢,而是卡在网络前期环节。重点盯这几个字段(单位毫秒,全基于
):
:DNS 查询耗时。超过 50ms 就该考虑
:TCP + TLS 握手耗时。移动端常达 200–400ms,
能提前完成这步
:实际网络传输(含 header + body)。若远大于首字节时间(
),说明 body 下载慢,可能需压缩或换 CDN
:总耗时,但不能单独看——要拆解上面三段,才能定位瓶颈是 DNS、连接还是传输
对比 async/defer 实际效果
加了
或
不代表一定快,得验证是否真没阻塞 DOM 构建。
查
:如果这个时间点明显晚于第三方脚本的
,说明它仍在阻塞解析(比如用了同步
)
对
脚本,检查多个同域脚本的执行顺序是否混乱——若业务逻辑有依赖,乱序执行会导致错误,这时必须换
用
单独取某脚本记录,比对
和
,确认是否真正异步发起请求
performance.getEntriesByType("resource")window.addEventListener("load", ...)performance.entryType === "resource"PerformanceObservergetEntriesByTypehttps://cdn.segment.comdomainLookupStartconnectEndTiming-Allow-Origin: *initiatorType === "script"fetchXMLHttpRequestevalr.name.includes("google-analytics.com")r.name.includes("gtm.js")!r.name.includes(window.location.hostname)r.name.includes("/bundle.") || r.name.includes("sentry")performance.timeOrigindomainLookupEnd - domainLookupStartpreconnectconnectEnd - connectStartpreconnectresponseEnd - requestStartresponseStart - requestStartdurationasyncdeferperformance.getEntriesByType("navigation")[0].domContentLoadedEventStartresponseEnddocument.writeasyncdeferperformance.getEntriesByName("https://xxx.com/sdk.js")startTimefetchStart