首页
All Posts

前端全链路优化实战(三):指标采集如何拼成证据链

指标采集的目标不是“什么都记下来”,而是让排查人员能从一次用户访问中看到关键动作。它更像一组监测探针:页面体验、接口状态、资源异常和用户行为必须放在一起看。只看一个指标很容易误判,页面慢不一定是网络慢,接口成功不代表体验好,脚本没...

指标采集监测台

指标采集的目标不是“什么都记下来”,而是让排查人员能从一次用户访问中看到关键动作。它更像一组监测探针:页面体验、接口状态、资源异常和用户行为必须放在一起看。只看一个指标很容易误判,页面慢不一定是网络慢,接口成功不代表体验好,脚本没报错也不代表交互顺畅。

一个实用的采集体系,至少应该覆盖四类信号:网页体验、接口状态、资源与脚本异常、用户行为。

网页体验:用 Web Vitals 接近用户感受

传统 Performance 指标很细,但不一定能直接解释用户体验。比如 DOMContentLoaded 很快,不代表用户已经看到主内容;load 完成很慢,也不代表页面不可用。Web Vitals 的价值在于,它更接近用户感受。

几个指标可以这样理解:

  • FCP:用户第一次看到页面有内容。
  • LCP:用户看到页面主要内容。
  • INP:用户交互后页面响应是否及时。
  • CLS:页面是否突然跳动,影响点击和阅读。
  • TTFB:浏览器收到服务端第一个字节用了多久。

采集这些指标时,不能只记录数值,还要记录上下文。比如 LCP 是哪一个元素,元素是图片、文本块还是视频封面;INP 对应的是哪次点击;CLS 发生时页面上是什么动态内容。只有数值没有上下文,就像只知道比分落后,却不知道哪个回合丢分。

接口状态:别只看失败,也要看慢和中断

接口采集常见误区是只记录非 2xx 状态码。实际线上问题里,慢请求、业务错误、请求中断、超时、重复请求同样重要。

应该关注的维度包括:

  • HTTP 状态码,例如 404、500、502、504。
  • 业务错误码,例如库存不足、权限失效、风控拒绝。
  • 请求耗时,尤其是 P95、P99 而不是平均值。
  • 是否超时,超时时间是多少。
  • 是否由用户离开页面或取消操作导致中断。
  • 请求发起时对应哪个页面动作。
  • 请求是否携带 trace 信息,能否关联后端。

举个例子,用户点击“支付”后页面没有反应。接口日志显示支付接口返回 200,但业务错误码是 PAYMENT_RISK_REJECTED,前端没有正确提示。这个问题不是接口失败,而是业务错误处理不完整。如果采集只看 HTTP 状态码,就会漏掉真实原因。

资源和脚本:前端资产也是用户体验的一部分

资源加载失败会直接影响体验。图片加载失败可能导致内容缺失,CSS 加载失败会造成页面错乱,JS 加载失败会让功能不可用。脚本运行时异常则可能只影响部分用户、部分浏览器或部分操作路径。

全局资源监听可以关注 error 事件中的资源类型、URL、页面版本、网络状态、是否跨域。脚本异常则需要记录 message、stack、文件、行列号、是否来自 Promise rejection。

这里有两个细节:

第一,跨域脚本如果没有正确设置 crossorigin 和响应头,错误信息可能只剩下 Script error。这会让排查失去堆栈。关键脚本要提前设计跨域错误采集方案。

第二,加载慢的资源不一定触发错误事件。慢图片、慢字体、慢 JS 会拖累 LCP、FCP 或交互响应。资源性能需要结合 PerformanceResourceTiming 采集,而不是只等失败。

用户行为:错误前的动作比错误本身更重要

很多前端异常都需要用户行为才能复现。只记录错误发生点,就像只看到最后一个告警,却不知道之前用户做了什么、接口经历了什么、资源是否加载失败。

行为采集可以分成两层:

  • 全局行为:点击、输入、滚动、路由跳转、页面隐藏、页面恢复。
  • 业务行为:提交订单、添加购物车、领取优惠券、切换规格、上传文件。

全局行为用于还原基本路径,业务行为用于理解业务语义。采集时不要记录用户输入的敏感内容,可以记录字段名、输入长度、操作类型,不记录具体值。

行为日志最好做成环形缓冲区。平时不必每个动作都立即上报,而是在发生异常时,把错误前最近 10 到 20 个关键动作附带上报。这样既能控制日志量,又能保留复现线索。

自定义指标:给业务问题留一个扩展口

通用指标无法覆盖所有业务场景。比如一个在线编辑器需要关注文档保存队列,一个视频页需要关注首帧和缓冲,一个表单页需要关注校验失败分布。这些都需要自定义指标。

自定义指标不要做成随意 console.log 式的接口,而要保留统一字段:

{
  "type": "custom_metric",
  "name": "checkout_coupon_apply",
  "level": "warn",
  "value": 1,
  "tags": {
    "couponType": "new_user",
    "scene": "checkout"
  }
}

name 用于聚合,level 用于告警,value 用于统计,tags 用于细分。这样业务团队能扩展自己的观测点,同时不会破坏全局数据结构。

上报方式:采集不能反过来伤害体验

数据上报本身也会影响用户体验,所以要轻量。常见方案有三类:

  • sendBeacon:适合页面卸载、后台上报,不阻塞跳转。
  • 图片上报:兼容性好,适合简单日志,但容量和语义有限。
  • 批量异步上报:适合常规日志,可压缩、合并、采样。

不要把核心日志全部放在同步请求里。页面退出时阻塞用户,只会让监控系统变成新的性能问题。更合理的做法是:错误日志优先级最高,关键业务日志次之,普通行为日志采样并批量上报。

指标采集的最终目标,是拼出证据链。Web Vitals 告诉你用户感受,接口指标告诉你数据通路,资源和脚本异常告诉你前端资产状态,用户行为告诉你问题发生前的路径。四类信号合在一起,才能把“感觉不对”变成“可以定位”。