performanceobserver 必须在 内同步执行初始化,否则会丢失 fcp/lcp 等首屏指标;需分别监听 paint 和 largest-contentful-paint 类型;cls 计算须过滤 hadrecentinput;longtask 应设 ≥100ms 阈值。

PerformanceObserver 必须在 里初始化,否则会丢掉首屏指标
浏览器一旦开始渲染,first-contentful-paint、largest-contentful-paint 这类关键 entry 就可能已生成。如果等 DOMContentLoaded 甚至 load 事件后再创建 PerformanceObserver,这些 entry 就永远捕获不到。
常见错误现象:本地调试时 FCP/LCP 数据始终为空或为 0;Lighthouse 测出有值,但 RUM 上报却缺失。
- 把
PerformanceObserver实例化代码直接写在的<script></script>标签内(不加defer或async) - 避免封装成函数再调用——函数定义本身不触发监听,必须立即执行
observe() - 不要依赖第三方 SDK 的“初始化完成”钩子,它大概率晚于首屏绘制
监听 paint 和 largest-contentful-paint 不能混用同一 observer
paint 类型返回的是 PerformancePaintTiming 实例,含 first-paint 和 first-contentful-paint;而 largest-contentful-paint 是独立类型,返回 LargestContentfulPaint 实例。两者字段结构、触发时机、生命周期完全不同。
使用场景差异:
-
paint:适合捕获白屏结束(FP)和首屏内容可见(FCP),用于诊断渲染阻塞 -
largest-contentful-paint:只在最大内容元素完成绘制时触发一次,且可能被后续更大元素覆盖(需取list.getEntries().pop()) - 混用会导致回调中
entry.name判定混乱,或漏掉 LCP 的最终值
正确写法是分开声明两个 observer:
const fpObserver = new PerformanceObserver(list => {
for (const entry of list.getEntries()) {
if (entry.name === 'first-contentful-paint') {
sendToMonitoring('FCP', entry.startTime);
}
}
});
fpObserver.observe({ entryTypes: ['paint'] });
const lcpObserver = new PerformanceObserver(list => {
const lastEntry = list.getEntries().pop();
if (lastEntry) {
sendToMonitoring('LCP', lastEntry.startTime);
}
});
lcpObserver.observe({ entryTypes: ['largest-contentful-paint'] });
Layout Shift 数据要过滤用户输入,否则 CLS 严重失真
layout-shift entry 每次布局偏移都会触发,但 Web Vitals 规范明确要求:**仅统计用户无交互后的偏移**。否则滚动中图片加载、广告插入等正常行为会被计入 CLS,导致分数虚高。
关键判断字段是 entry.hadRecentInput,它在用户操作后约 500ms 内为 true。
- 必须检查
!entry.hadRecentInput,否则 iOS Safari 和 Chrome 120+ 上的 CLS 值可能比真实体验高 3–5 倍 - 不要用
entry.startTime > 0或entry.value > 0替代该判断——它们无法区分是否由用户行为引发 - 累积时注意浮点精度:
cumulativeLayoutShiftScore += entry.value,不是+= 1
LongTask 监听必须设阈值,否则上报量爆炸
longtask entry 在现代浏览器中非常频繁(尤其含复杂框架的 SPA),每个超过 50ms 的任务都会记录。不加过滤直接上报,单页可能产生数百条日志,既压垮采集服务,也掩盖真正瓶颈。
性能/兼容性影响:
- Chrome 和 Edge 支持
longtask,但 Safari 目前完全不支持(截至 2026 年 4 月) - 建议只上报
entry.duration >= 100的任务,兼顾可观测性与信噪比 - 搭配
entry.attribution字段可定位到具体脚本 URL 和函数名(需开启performance.setResourceTimingBufferSize(1000))
容易踩的坑:直接监听却不做 duration 过滤,上线后监控平台告警风暴,运维第一反应是“前端埋点炸了”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











