直接调用performance.getEntriesByType('resource')可获取静态资源完整时序数据,但需拆解DNS、TCP、TTFB、下载四阶段定位瓶颈;跨域资源须服务端配置Timing-Allow-Origin头,沙箱iframe需allow-performance权限,推荐用buffered:true的PerformanceObserver实时捕获。

直接用 performance.getEntriesByType('resource') 查每个资源的耗时,再按 DNS、连接、首字节、下载四段拆解,就能一眼看出卡在哪——不是看总时间,而是看哪一段异常拉长。
先确保能拿到完整资源数据
很多情况下调用 getEntriesByType('resource') 返回空数组,并非没加载,而是浏览器根本没记录。常见原因有三个:跨域资源没配 Timing-Allow-Origin 响应头;页面嵌在沙箱 iframe 里但没加 allow-performance 权限;或者调用太晚,条目已被清理。
- 第三方脚本或 CDN 资源必须返回响应头:
Timing-Allow-Origin: https://your-domain.com(不能写*) - 沙箱 iframe 需显式声明:
<iframe sandbox="allow-scripts allow-performance"> - 别等
window.onload才查,改用PerformanceObserver并开启buffered: true,保证页面已加载的资源不丢失
重点盯四个阶段,而不是总耗时
单看 duration 容易误判。真正卡点藏在中间环节:
-
DNS 查询慢:计算
domainLookupEnd - domainLookupStart,超过 50ms 就该考虑<link rel="preconnect"> -
TCP + TLS 握手久:看
connectEnd - connectStart,移动端常达 200–400ms,preconnect可提前完成这步 -
后端响应拖沓:
responseStart - requestStart(即 TTFB)持续 > 500ms,要查 SSR 渲染逻辑或 CDN 缓存配置 -
下载本身慢:对比
responseEnd - responseStart和资源体积,若每 MB 耗时远超 1s,说明压缩未生效或带宽受限
快速筛选出问题资源
不用人工翻列表,用代码过滤出“最可疑”的几个:
立即学习“前端免费学习笔记(深入)”;
- 找加载最慢的前 3 个:
entries.sort((a, b) => b.duration - a.duration).slice(0, 3) - 专盯阻塞渲染的 CSS/字体:
entry.initiatorType === 'link' && entry.name.endsWith('.css')或entry.name.endsWith('.woff2') - 识别第三方脚本:
!entry.name.includes(location.hostname) && (entry.name.includes('analytics') || entry.name.includes('cdn')) - 检查是否被缓存:
entry.transferSize === 0表示走了内存或磁盘缓存,transferSize > decodedBodySize * 2则说明压缩失效
结合 Navigation Timing 锚定影响范围
单个资源慢不一定拖累首屏。把它和 navigation 条目对齐,看是否发生在 FCP 之前:
- 取
performance.getEntriesByType('navigation')[0],拿到firstContentfulPaint时间戳 - 把资源
startTime和它比:若资源responseEnd > FCP,且它是关键 CSS 或字体,那它就是首屏瓶颈 - 若资源在 FCP 后才开始加载,再慢也不影响用户第一眼体验,可降优先级或懒加载



















