最稳定精准的前端性能监控方案是:先用performance.getentriesbytype('navigation')[0]获取导航时间线计算ttfb、白屏、dom就绪等耗时;再通过提前注册的performanceobserver监听paint和largest-contentful-paint类型捕获fcp/lcp;最后用getentriesbytype('resource')分析带crossorigin的资源加载瓶颈,并用sendbeacon轻量上报。

直接用 performance.getEntriesByType('navigation') 获取首屏关键阶段耗时,配合 PerformanceObserver 捕获 FCP/LCP 等渲染指标,再用 getEntriesByType('resource') 定位慢资源——这是当前最稳定、精度高、兼容性好的做法。
优先获取导航性能数据
页面加载的核心时间线藏在 navigation 类型条目中,不是已废弃的 performance.timing:
- 调用
performance.getEntriesByType('navigation')[0],确保在document.readyState === 'complete'或window.addEventListener('load', ...)后执行,否则返回空数组 - 从中提取
startTime(等价于navigationStart)、responseStart、domContentLoadedEventStart、loadEventEnd等字段 - 计算关键耗时:
• TTFB =responseStart - requestStart(注意nav.type === 'back_forward'时responseStart可能为 0,需跳过)
• 白屏时间 ≈domLoading - startTime
• DOM 就绪时间 =domContentLoadedEventEnd - startTime
• 完整加载时间 =loadEventEnd - startTime
必须提前注册 PerformanceObserver 监听渲染指标
FCP(首次内容绘制)和 LCP(最大内容绘制)是一过性事件,延迟注册就无法捕获:
- 把
new PerformanceObserver(...)的代码写在内的同步<script></script>中,不加defer、不包函数、不等任何钩子 - 监听
paint类型获取 FCP:entry.name === 'first-contentful-paint' - 单独监听
largest-contentful-paint类型获取 LCP;取list.getEntries().pop()才是最终稳定值,因为 LCP 可能被后续更大元素覆盖
分析资源加载瓶颈
performance.getEntriesByType('resource') 能暴露图片、脚本、字体等真实加载表现,但要注意限制:
- 跨域资源默认屏蔽
duration和部分时间戳,必须在标签上加crossorigin="anonymous"(如<script src="..." crossorigin></script>),动态创建的资源还需手动设crossOrigin = 'anonymous' - 只在
load事件后调用,否则未完成加载的资源duration仍为 0 - 过滤掉
entry.duration 或 <code>entry.initiatorType === ''的条目,它们多是预连接、CORS 失败或空响应残留 - 重点关注
transferSize(实际传输体积)和decodedBodySize(解码后大小),识别未压缩、未分片或缓存失效问题
上报与兼容性处理
监控逻辑要轻量、可靠、可降级:
- 使用
navigator.sendBeacon()上报数据,确保页面卸载前也能发出请求 - 对重复访问用户采样上报(如 10%),或仅在关键指标异常时(如 FCP > 3s、TTFB > 800ms)触发完整采集
- 先检测
performance.getEntriesByType是否存在;不存在则回退到performance.navigationStart或performance.timing(仅作兜底);极端情况 fallback 到Date.now() - 所有初始化代码务必放在页面最顶部的内联
<script></script>中,避免因脚本延迟错过早期时间点
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











