PerformanceObserver监听paint类型可准确捕获FP和FCP,需在顶部尽早初始化;FP是首次像素绘制(如背景色),FCP是首个内容元素(文本/图片等)绘制,二者时间接近但FCP更反映用户真实感知。

直接用 PerformanceObserver 监听 paint 类型事件,就能准确捕获首次渲染(FP)和首次内容绘制(FCP)两个时间点。关键在于必须在 里尽早初始化,否则容易错过首屏关键事件。
用 PerformanceObserver 捕获 FP 和 FCP
Paint Timing API 通过 PerformancePaintTiming 接口暴露 FP 和 FCP。浏览器在完成对应绘制阶段后,会触发 paint 类型的性能条目。推荐写法如下:
- 把 observer 初始化代码放在
最顶部,确保在任何资源加载或脚本执行前就位 - 监听
entry.name === 'first-paint'或'first-contentful-paint',取entry.startTime即为毫秒级时间戳 - 不要依赖
performance.getEntriesByType('paint')在页面后期调用——TV 浏览器或弱网环境可能已清空 buffer,导致拿不到数据
FP 和 FCP 的实际区别在哪
FP 是浏览器第一次把像素画到屏幕上的时刻,比如背景色、边框等纯样式渲染;FCP 则要求有“内容”,例如:
- 非空文本节点(哪怕只有一个空格,只要不是全空白)
- 已加载完成的
<img alt="如何使用HTML5中PaintTiming监控网页首次渲染点与内容展示点" >或带有效background-image且background-size不为 0 的元素 -
<canvas></canvas>已执行过绘图命令,或<video></video>显示出首帧/海报帧
多数情况下 FP 和 FCP 时间接近甚至相同,但若页面先渲染白底再加载文字,两者就会分离——这时 FCP 更反映用户真实感知。
立即学习“前端免费学习笔记(深入)”;
兼容性与降级处理
不是所有环境都完整支持 Paint Timing:
- Tizen 4.0 以下版本不支持
getEntriesByType('paint'),需 fallback:用document.readyState === 'interactive'配合setTimeout轮询document.body.offsetHeight > 0或检测关键 DOM 节点是否可获取尺寸 - TV 浏览器可能对高精度计时器降频,
console.time()不准,一律改用performance.now()打点 - 务必做判空处理:
performance.getEntriesByType('paint')可能返回空数组,navigation条目在单页应用中只触发一次,后续路由跳转不会更新
上报数据要注意什么
监控数据要在页面卸载前发出,避免丢失:
- 用
navigator.sendBeacon()发送聚合后的指标,它能在页面关闭时异步发出请求 - 不要等到
beforeunload或unload事件里才收集数据——此时部分 performance entry 可能已被清理 - 对 FCP 这类关键指标,建议在 observer 回调中立即上报,而不是攒到 unload 时统一发



















