如何通过HTML获取页面性能核心指标FCP、LCP、FID和CLS?
- 内容介绍
- 文章标签
- 相关推荐
本文共计846个文字,预计阅读时间需要4分钟。
可以使用浏览器内置的 `PerformanceObserver API 获取 FCP、LCP、CLS 等指标,但 FID 已被弃用,建议使用 `INP`;所有指标均需在页面加载早期注册监听,否则会丢失关键事件。
用 PerformanceObserver 监听 LCP 和 CLS
这两个指标有原生的观察类型,注册后能捕获所有相关条目。注意必须设置 buffered: true,否则页面加载完成后再注册就收不到历史记录。
常见错误:只监听一次就结束,或没加 buffered 导致本地调试时看不到数据。
-
LCP对应type: 'largest-contentful-paint',entry.value 是毫秒值 -
CLS对应type: 'layout-shift',要累加所有 entry 的value(不是取最后一次) - CLS 条目可能在页面卸载前持续发生,建议在
visibilitychange为hidden时汇总上报
FCP 不能直接监听,得靠 performance.getEntriesByName()
PerformanceObserver 不支持 paint 类型的实时监听(Chrome 120+ 才开始实验性支持),所以更稳妥的方式是:在 load 事件后主动查表。
立即学习“前端免费学习笔记(深入)”;
使用场景:首屏性能埋点、自动化测试脚本中提取指标。
- 调用
performance.getEntriesByName('first-contentful-paint', 'paint'),返回数组,取[0].startTime - 如果返回空数组,说明页面还没触发 FCP(极少见),可设 5s 超时兜底
- 注意 Safari 对
paint类型支持不一致,部分版本需 fallback 到performance.timing计算
别再用 FID,改用 INP 并注意采样逻辑
FID 在 2024 年已被 Google 正式弃用,INP 才是当前标准交互指标。它不是单次延迟,而是取页面生命周期内最差的一次交互响应(含输入 + 渲染)。
容易踩的坑:以为和 FID 一样只监听一次,或误把 event.duration 当成 INP 值。
- 监听
type: 'event',过滤出entry.interactionId > 0的条目 - INP 是所有符合条件条目中最大的
duration,不是平均值或首次值 - Chrome 会自动聚合同一交互的多个任务,但需确保监听在
documentready 前就位,否则错过首屏点击
本地快速验证指标是否正常上报
不用等线上埋点,打开 Chrome DevTools → Application → Clear storage → 刷新页面,然后在 Console 粘贴这段最小化代码:
new PerformanceObserver(e => e.getEntries().forEach(console.log)).observe({type: 'layout-shift', buffered: true}); new PerformanceObserver(e => e.getEntries().forEach(console.log)).observe({type: 'largest-contentful-paint', buffered: true}); console.log('FCP:', performance.getEntriesByName('first-contentful-paint', 'paint')[0]?.startTime);
如果控制台输出了 startTime、value、duration 等字段,说明采集链路通了。真正上线时,要注意避免重复注册 observer,也别在 SPA 路由切换后忘记重置 CLS 累计值。
本文共计846个文字,预计阅读时间需要4分钟。
可以使用浏览器内置的 `PerformanceObserver API 获取 FCP、LCP、CLS 等指标,但 FID 已被弃用,建议使用 `INP`;所有指标均需在页面加载早期注册监听,否则会丢失关键事件。
用 PerformanceObserver 监听 LCP 和 CLS
这两个指标有原生的观察类型,注册后能捕获所有相关条目。注意必须设置 buffered: true,否则页面加载完成后再注册就收不到历史记录。
常见错误:只监听一次就结束,或没加 buffered 导致本地调试时看不到数据。
-
LCP对应type: 'largest-contentful-paint',entry.value 是毫秒值 -
CLS对应type: 'layout-shift',要累加所有 entry 的value(不是取最后一次) - CLS 条目可能在页面卸载前持续发生,建议在
visibilitychange为hidden时汇总上报
FCP 不能直接监听,得靠 performance.getEntriesByName()
PerformanceObserver 不支持 paint 类型的实时监听(Chrome 120+ 才开始实验性支持),所以更稳妥的方式是:在 load 事件后主动查表。
立即学习“前端免费学习笔记(深入)”;
使用场景:首屏性能埋点、自动化测试脚本中提取指标。
- 调用
performance.getEntriesByName('first-contentful-paint', 'paint'),返回数组,取[0].startTime - 如果返回空数组,说明页面还没触发 FCP(极少见),可设 5s 超时兜底
- 注意 Safari 对
paint类型支持不一致,部分版本需 fallback 到performance.timing计算
别再用 FID,改用 INP 并注意采样逻辑
FID 在 2024 年已被 Google 正式弃用,INP 才是当前标准交互指标。它不是单次延迟,而是取页面生命周期内最差的一次交互响应(含输入 + 渲染)。
容易踩的坑:以为和 FID 一样只监听一次,或误把 event.duration 当成 INP 值。
- 监听
type: 'event',过滤出entry.interactionId > 0的条目 - INP 是所有符合条件条目中最大的
duration,不是平均值或首次值 - Chrome 会自动聚合同一交互的多个任务,但需确保监听在
documentready 前就位,否则错过首屏点击
本地快速验证指标是否正常上报
不用等线上埋点,打开 Chrome DevTools → Application → Clear storage → 刷新页面,然后在 Console 粘贴这段最小化代码:
new PerformanceObserver(e => e.getEntries().forEach(console.log)).observe({type: 'layout-shift', buffered: true}); new PerformanceObserver(e => e.getEntries().forEach(console.log)).observe({type: 'largest-contentful-paint', buffered: true}); console.log('FCP:', performance.getEntriesByName('first-contentful-paint', 'paint')[0]?.startTime);
如果控制台输出了 startTime、value、duration 等字段,说明采集链路通了。真正上线时,要注意避免重复注册 observer,也别在 SPA 路由切换后忘记重置 CLS 累计值。

