一个营销页面,Lighthouse跑出95分,CrUX却显示68%的真实用户正在经历"差"的LCP。同一个URL,两个结果。
流量主要来自东南亚用户,中端安卓机,4G网络。Lighthouse模拟的是Moto G4,但用的是本地高速网络和预热过的服务器。模拟设备没问题,网络条件和服务器地理位置才是鸿沟。
这就是真实用户数据(field data)要填补的缺口。Lighthouse告诉你控制环境下的可能性,真实用户数据告诉你实际发生了什么。
先用手头已有的东西。查Chrome UX Report。PageSpeed Insights能显示任何有足够流量的URL的CrUX数据——真实的LCP、INP、CLS分布,分成良好/需改进/差三档。Google Search Console的核心网页指标报告按页面组聚合同样的数据。
CrUX有两个局限要知道。它只包含启用了使用报告的Chrome用户访问过的URL,低流量页面不会显示。而且是28天滚动窗口聚合,意味着上周上线的性能回退可能还要三周才完全显现。
对大多数团队,CrUX是正确第一站。如果CrUX数据看起来正常,合成测试大概够用。如果不行——或者流量不够进不了CrUX——你需要自己的RUM(真实用户监控)管道。
web-vitals库是正确的根基。它处理了原始PerformanceObserver API留给你的归因和计算细节。报告的值和Google用于CrUX的相同,这很重要,当你试图把内部数据与影响搜索排名的因素关联时。
import { onLCP, onINP, onCLS } from 'web-vitals/attribution';
function sendToAnalytics(metric) {
fetch('/api/vitals', {
method: 'POST',
body: JSON.stringify({
name: metric.name,
value: metric.value,
rating: metric.rating, // 'good' | 'needs-improvement' | 'poor'
attribution: metric.attribution,
page: location.pathname,
navigationType: metric.navigationType,
}),
keepalive: true,
onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);
/attribution导入是关键。INP的metric.attribution包含交互目标、事件类型,以及三阶段分解——输入延迟、处理时间、呈现延迟——告诉你时间耗在哪。CLS则包含移动的元素和移动距离。这些归因数据让真实测量可行动,而不只是装饰。
fetch上的keepalive: true确保即使用户在请求完成前导航离开,请求也能完成。
下结论前先细分。原始平均值几乎掩盖一切。p75 LCP 2.4秒看起来不错——直到按设备类型拆分,发现桌面用户1.1秒,移动用户3.8秒。或者按页面拆分,发现90%的糟糕体验集中在三个模板页上。
关键的细分维度:设备内存(通过navigator.deviceMemory)、连接类型(navigator.connection.effectiveType)、缓存状态(navigationType区分navigate/reload/back-forward)、地理位置(如果业务相关)。
不要只收集,要建立反馈回路。把RUM数据接到告警系统——不是针对平均值,而是针对p75或p95的回归。把归因数据接到开发工作流:INP延迟高?看是哪个组件的交互事件处理在阻塞。CLS突发?看是哪个图片或广告位没预留空间。
真实用户数据的价值不在报告,在缩小"我们认为的性能"和"用户实际感受的性能"之间的差距。Lighthouse是起点,不是终点。
热门跟贴