实验室测和真实用户测的区别
性能优化最容易犯的错,是只在自己电脑上用 Lighthouse 跑一遍就觉得“性能很好”。但你本机的网速、设备、缓存都和真实用户差很远:可能用着 4G 慢网、低端安卓机、还开着一堆标签页。实验室测(Lab)和真实用户监控(RUM)回答的是两个问题:实验室告诉你“在理想条件下这个页面理论上多快”,RUM 告诉你“真实用户群体实际有多快、慢在哪里”。
RUM(Real User Monitoring)是把一段轻量埋点脚本放进线上页面,收集每个真实用户的性能数据、聚合成指标。只有跑了 RUM,你才知道有百分之多少的用户在打开页面时卡了三秒、多少人因为交互卡顿流失。优化不能拍脑袋,先得有数据。
- RUM真实用户监控,线上采集、聚合、告警。
- Web VitalsGoogle 定的一组体验核心指标。
- LCP最大内容多久画出来,衡量加载速度。
- INP交互到响应多快,衡量操作流畅度。
Web Vitals 三个核心指标
Web Vitals 是 Google 推出的一套统一指标,用来衡量网页体验好坏。三个核心指标分别覆盖加载、交互、视觉稳定三个维度,并且给了“好、需改进、差”的量化阈值:
- LCP(最大内容绘制):加载性能,小于 2.5 秒为好。
- INP(交互到下次绘制):交互响应,小于 200 毫秒为好。它在 2024 年取代了旧的 FID。
- CLS(累积布局偏移):视觉稳定,小于 0.1 为好。
用这三个指标配合 RUM,就能把“页面卡不卡”从主观感觉变成可监控、可告警、可对比的数字。
LCP:最大内容绘制
LCP 统计的是页面里最大的那块内容(通常是首屏主图或一大段文字)画出来的时间。它比“页面全部加载完”更贴近用户感受——用户主要等的就是主内容出现,而不是边角的小字。
拖慢 LCP 的常见原因:主图太大没压缩、首屏关键资源被 CSS/JS 阻塞、字体加载慢导致文字延后渲染。优化方向集中在让首屏主内容尽快出现:压缩并预加载主图、给关键资源加 preload、用 font-display 避免文字白屏。
INP:交互到下一次绘制
INP 衡量的是用户每一次交互(点击、输入)到浏览器真正画出响应之间的总耗时。它取代了过去只测首次点击的 FID,更能反映“整个使用过程里操作是否跟手”。INP 高,意味着用户点按钮、输文字时页面卡顿、跟不上手。
INP 高基本都是主线程被长任务占满:一个 JS 事件回调执行了几百毫秒,期间所有交互都排队等着。优化办法是拆解长任务、把重计算移出主线程(Web Worker)、减少不必要的同步渲染。长任务的识别可以看 PerformanceObserver 记录的 longtask。
CLS:累积布局偏移
CLS 统计的是页面在加载过程中,元素意外跳动的总程度。最典型的糟糕体验:你正要点一个按钮,图片加载出来把按钮往下顶了一块,结果点到了别处。这种“布局偏移”直接决定页面用起来是否稳。
降低 CLS 的核心就一句话:给媒体元素预留尺寸。图片、视频、广告位都写好宽高或 aspect-ratio,浏览器在它们加载前就留好位置,就不会顶跑别的内容。动态注入的内容也要放在布局流的预期位置,别在用户已经看到的区域突然插一块出来。
<img src="hero.jpg" width="800" height="450"
style="aspect-ratio: 16/9">
/* 给图片预留宽高比,加载时不再挤压布局 */
埋点采集与上报
采集 Web Vitals 不用自己从零算,浏览器自带 PerformanceObserver,官方还有 web-vitals 这个小库。基本做法是:引入库、注册回调、在指标稳定后用 sendBeacon 把数据异步发回后端,不阻塞页面、不丢数据。
import { onLCP, onINP, onCLS } from 'web-vitals';
onLCP(send); onINP(send); onCLS(send);
function send(metric) {
// 异步上报,页面卸载也不丢
navigator.sendBeacon('/collect', JSON.stringify({
name: metric.name, value: metric.value,
id: metric.id
}));
}
上报后端按页面、设备、网络、地区做聚合,看分位数(P75、P95)而不是平均值——平均值会把慢用户掩盖掉。再对低于阈值的比例设告警,一旦某个版本上线后 INP 劣化,能立刻发现。
实战清单
落地清单:
- 别只信实验室跑分,线上一定跑 RUM 看真实用户。
- 盯 LCP、INP、CLS 三个 Web Vitals,按 P75/P95 看分布。
- LCP 差就优化首屏主图和关键资源加载。
- INP 差就拆解长任务、重计算丢进 Web Worker。
- CLS 差就给图片视频预留宽高比,别让内容跳动。
- 用 web-vitals 库采集、sendBeacon 上报,设阈值告警。
性能监控的价值,是把“感觉慢”变成“哪个页面、哪类用户、卡在哪一步”的具体数字。把 LCP、INP、CLS 三个 Web Vitals 接进 RUM 持续盯着,每次发版都能对比,性能优化才真正有据可依、有的放矢。