在 vue 3 中可用 web-vitals 库结合 performance api 可靠采集 lcp、fid、cls、fcp、inp 等 core web vitals 指标,需在 onmounted 阶段注册监听、带上下文轻量上报,并避免 dom 未就绪或重复注册等常见陷阱。

直接用 web-vitals 库配合浏览器原生 Performance API,就能在 Vue 应用中可靠采集 Core Web Vitals(LCP、FID、CLS、FCP、INP 等)。关键不是“自己封装 API”,而是选对时机、传好上下文、轻量上报。
在 Vue 3 中注册核心指标监听
把监听逻辑放在应用初始化阶段(如 main.ts 或 App.vue 的 onMounted),确保覆盖首屏和后续路由。推荐使用 Composition API 封装:
// composables/useWebVitals.ts
import { onMounted } from 'vue'
import {
onLCP,
onFID,
onCLS,
onFCP,
onINP,
type Metric
} from 'web-vitals'
export function useWebVitals() {
onMounted(() => {
// 每个指标只监听一次,自动触发回调
onLCP(sendToMonitoring)
onFID(sendToMonitoring)
onCLS(sendToMonitoring)
onFCP(sendToMonitoring)
onINP(sendToMonitoring)
})
}
function sendToMonitoring(metric: Metric) {
// 上报时带上业务上下文,比如当前路由、设备类型、网络状态
const data = {
name: metric.name,
value: Math.round(metric.value),
rating: metric.rating, // 'good' | 'needs-improvement' | 'poor'
id: metric.id, // 用于去重和会话追踪
url: window.location.pathname,
ua: navigator.userAgent,
effectiveType: navigator?.connection?.effectiveType || 'unknown',
timestamp: Date.now()
}
// 使用 sendBeacon 确保页面卸载前也能发出
if (navigator.sendBeacon) {
navigator.sendBeacon('/api/perf', JSON.stringify(data))
} else {
fetch('/api/perf', {
method: 'POST',
body: JSON.stringify(data),
keepalive: true
})
}
}
重点采集哪些指标?按用户感知阶段分
加载阶段:LCP(最大内容绘制)、FCP(首次内容绘制)、TTFB(首字节时间)
→ 反映“页面多久开始有东西可看”交互阶段:FID(已弃用,但旧项目仍可能用)、INP(现推荐替代指标)
→ 反映“点按钮后多久有反馈”,尤其适合表单提交、菜单展开等操作稳定性阶段:CLS(累积布局偏移)
→ 反映“页面会不会突然跳动”,对后台系统、数据看板类 Vue 应用特别关键(比如 RuoYi-Vue3 中动态插入表格行易引发 CLS)
避免常见陷阱
下载 Comet AI 浏览器,体验由 Perplexity AI 驱动的革命性上网方式。内置 AI 助手可实时总结网页、跨标签页对比信息、自动执行任务。告别繁琐操作,让 AI 成为你的浏览副驾,大幅提升研究与工作效率。支持 Windows、macOS、Android 和 iOS。
- 不要在
created或setup里调用onXXX—— 此时 DOM 可能未就绪,LCP/FCP 会漏报 - 不要重复注册同一指标(如多次调用
onLCP)——web-vitals内部已做防重,但业务层建议只在根组件初始化一次 - 不要直接
console.log(metric)就完事 —— 必须带上下文上报,否则无法关联到具体页面、用户或错误场景 - INP 需要完整交互周期(从输入到下一次绘制),所以它默认在页面生命周期末期才触发,需确保上报通道在
beforeunload前仍可用
对 Vue Router 项目做增强
可在路由守卫中补充页面级维度:
router.beforeEach((to) => {
// 打标记,辅助归因
performance.mark(`route-start-${to.path}`)
})
router.afterEach((to) => {
performance.measure(`route-load-${to.path}`, `route-start-${to.path}`)
})
这样上报的 LCP 数据就能和 to.path 关联,方便在 Grafana 或自建看板里按路由分析性能水位。
不复杂但容易忽略
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










