你上线了一个页面,自认为飞快。但用户那边转圈转了三秒,走了。你浑然不知。今天我们来装一套“网页心电图仪”——前端性能监控。它能告诉你:用户打开你的网站,到底有多卡?哪里卡?卡的人多不多?不用等用户骂你,你就知道该优化哪了。

前言

性能优化不是“我觉得快”,而是“数据证明快”。没有监控的优化,就像闭着眼睛射箭——中了是运气,脱靶是常态。

Google 定义了三个核心指标(Core Web Vitals):LCP(加载速度)、FID(交互响应)、CLS(视觉稳定)。加上我们自己业务关心的指标(比如首屏时间、API耗时),组合起来就是你的“网页健康报告”。

今天我们就来搭一套轻量级前端性能监控,从采集到上报,再到报警,一条龙。

一、三大核心指标:你的网页“体检三项”

LCP(最大内容绘制):加载速度的“裁判”

LCP 测量页面主要内容(比如大图、标题、视频)加载完成的时间。理想值:2.5秒以内

什么算“主要内容”?就是用户第一眼看到的那个最大的元素。可能是背景图,可能是大标题,也可能是视频封面。

FID(首次输入延迟):交互响应的“秒表”

用户第一次点击、触摸或按键,到浏览器真正开始处理的时间。理想值:100毫秒以内

如果你的JS主线程被长任务阻塞,用户点了按钮没反应,FID就会高。用户会觉得“这网站卡死了”。

CLS(累计布局偏移):视觉稳定的“防抖测试”

页面加载过程中,元素突然位移(比如图片加载出来把按钮挤下去了)。理想值:0.1以内

CLS 高,用户容易点错按钮,比如本来要点“购买”,结果图片加载完,按钮被挤开,点到了“不感兴趣”。

二、怎么采集这些指标?用 web-vitals

Google 官方提供了 web-vitals 库,几行代码就能拿到 LCP、FID、CLS。

npm install web-vitals
import { getLCP, getFID, getCLS } from 'web-vitals';

function sendToAnalytics({ name, value, id }) {
  // 上报到你的后端或第三方服务
  navigator.sendBeacon('/api/perf', JSON.stringify({ name, value, id }));
}

getLCP(sendToAnalytics);
getFID(sendToAnalytics);
getCLS(sendToAnalytics);

注意:这些指标需要在页面加载完成后才能拿到,而且可能会多次更新(比如CLS会在整个页面生命周期中变化)。你可以选择只上报最终值,或者每次变化都上报(去重)。

三、其他重要指标:你自己更关心什么?

  • TTFB(首字节时间):从请求到服务器返回第一个字节。影响LCP,但更偏后端。
  • DOM Ready / Load 时间:传统指标,用于对比。
  • 首屏时间(自定义):比如你的页面有一个“主要内容区”,可以通过 MutationObserver 监听该区域出现的时间。
// 手动打点
const start = performance.now();
// 某个关键组件渲染完成后
const end = performance.now();
report('custom:firstContent', end - start);
  • API 响应时间:在 axios 拦截器里记录每个接口耗时。

四、上报策略:别把服务器打满

性能指标上报不能像打点日志那么频繁。策略:

  • 只上报一部分用户(采样),比如 10%。用随机数或用用户ID哈希。
  • 批量上报:收集多个指标,页面关闭前一次性发走(用 sendBeacon)。
  • 避免阻塞:用 requestIdleCallbacksetTimeout 低优先级上报。
if (Math.random() > 0.9) { // 10%采样
  navigator.sendBeacon('/api/perf', JSON.stringify(data));
}

五、报警与可视化:指标变差,立刻知道

光采集不上报等于没采。你需要一个后端接收数据,然后做可视化+报警。

  • 自建:用 Node + ClickHouse(或 InfluxDB)存储,Grafana 展示,设置阈值报警(比如 LCP P95 > 3s 发钉钉)。
  • 第三方Sentry(也能做性能监控)、DataDogGoogle Analytics(有 Core Web Vitals 报告)、阿里云ARMS

最简单的起步:把数据发到 Google Analytics(GA4),它有现成的 Web Vitals 报告。

import { getCLS, getFID, getLCP } from 'web-vitals';
import ga4 from 'react-ga4';

function sendToGA({ name, value, id }) {
  ga4.event('web_vitals', {
    event_category: 'Web Vitals',
    event_label: id,
    value: Math.round(name === 'CLS' ? value * 1000 : value),
    non_interaction: true,
  });
}

六、实战:完整的前端性能监控 SDK(简化版)

class PerfMonitor {
  constructor(options) {
    this.endpoint = options.endpoint;
    this.sampleRate = options.sampleRate || 0.1;
    this.init();
  }
  shouldReport() {
    return Math.random() < this.sampleRate;
  }
  send(data) {
    if (!this.shouldReport()) return;
    navigator.sendBeacon(this.endpoint, JSON.stringify(data));
  }
  init() {
    // Web Vitals
    import('web-vitals').then(({ getLCP, getFID, getCLS }) => {
      getLCS(metric => this.send(metric));
      getFID(metric => this.send(metric));
      getCLS(metric => this.send(metric));
    });
    // 自定义首屏时间
    if (document.readyState === 'loading') {
      document.addEventListener('DOMContentLoaded', () => {
        this.send({ type: 'domReady', value: performance.timing.domContentLoadedEventEnd - performance.timing.navigationStart });
      });
    }
    // 页面卸载时发送未发送的数据(可用Beacon队列)
  }
}
new PerfMonitor({ endpoint: '/api/perf', sampleRate: 0.1 });

七、常见坑点

  • CLS 在后台标签页不准确:用户切换标签页时,CLS 可能会误报。只在页面可见时收集。
  • 移动端 vs PC:指标分开统计,因为网络和设备差异大。
  • 缓存影响:已缓存的页面 LCP 会很快,应该区分首次访问和二次访问。

八、总结:让数据驱动你的优化

  • 监控 LCP、FID、CLS,用 web-vitals
  • 加上业务自定义指标(首屏时间、API 耗时)。
  • 采样上报,避免压力过大。
  • 用 GA4 或自建系统可视化+报警。
  • 定期查看指标趋势,倒退时立刻优化。

有了性能监控,你不再是“我觉得快”,而是“数据证明快”。老板问要不要优化,你甩出图表:“LCP 最近一周从2.1秒涨到3.5秒,用户流失率上升5%,建议立即优化图片。” 这才叫专业。

标签: none

添加新评论