3、性能分析工具(下):Lighthouse 与 Web Vitals(LCP、FID、CLS)在页面切换场景下的应用
上一讲我们聊了 Chrome DevTools 的 Performance 面板,那是微观层面的「手术刀」。今天要讲的 Lighthouse 和 Web Vitals,更像是宏观的「体检报告」和「健康标准」。
我个人习惯把这两者结合起来用:Lighthouse 做定量评分,Web Vitals 做定性监控。在页面切换场景下,它们能帮你回答三个核心问题:切换到底有多慢?慢在哪里?用户实际体验如何?
3.1 Lighthouse:不只是跑个分
很多人对 Lighthouse 的印象就是「点一下生成报告,看分数」。其实在页面切换优化中,它的价值远不止于此。
3.1.1 模拟模式 vs 真实模式
Lighthouse 提供两种运行模式,我建议你根据场景选择:
| 模式 | 适用场景 | 页面切换相关指标 | 我的建议 |
|---|---|---|---|
| 模拟 (Simulated) | 开发阶段快速验证 | FCP、LCP、TBT、SI | 每次改完代码跑一次,看趋势 |
| 真实 (DevTools) | 上线前最终验收 | 所有指标 + 真实网络延迟 | 用 3G 降速模拟弱网切换 |
3.1.2 页面切换场景下的关键审计项
Lighthouse 报告里有几十项审计,但针对页面切换,我只看这几个:
- Largest Contentful Paint (LCP) — 最大内容绘制时间。页面切换后,用户看到「主要内容」花了多久。
- Total Blocking Time (TBT) — 总阻塞时间。主线程被 JS 占用的总时长,直接影响切换响应。
- Speed Index (SI) — 速度指数。页面内容视觉填充的速度,切换时「白屏」的直观体现。
- Time to Interactive (TTI) — 可交互时间。用户能点击、滚动的时间点。
--preset=desktop 或手动触发路由切换来测二次加载。我曾经踩过这个坑——优化了半天首次加载,结果用户抱怨的是页面内跳转卡。
3.2 Web Vitals:用户真实体验的「金标准」
Lighthouse 跑分再高,也不代表用户实际体验好。为什么?因为 Lighthouse 是在「受控环境」下测试的。而 Web Vitals 是 Google 基于 Chrome 用户真实数据定义的指标。
说白了,Lighthouse 是「模拟考」,Web Vitals 是「高考」。
3.2.1 三大核心指标
Web Vitals 有三个核心指标,我分别说说它们在页面切换场景下的表现:
| 指标 | 全称 | 页面切换场景含义 | 良好阈值 | 差阈值 |
|---|---|---|---|---|
| LCP | Largest Contentful Paint | 切换后最大元素(图片、视频、大段文本)渲染时间 | ≤ 2.5s | > 4.0s |
| FID | First Input Delay | 用户首次与页面交互(点击、输入)到浏览器响应的延迟 | ≤ 100ms | > 300ms |
| CLS | Cumulative Layout Shift | 切换过程中页面布局的「跳动」程度 | ≤ 0.1 | > 0.25 |
3.2.2 页面切换场景的特殊性
你可能会问:「这些指标不是针对首次加载的吗?」
嗯,这里要注意:Web Vitals 的原始定义确实针对「页面加载」。但在 SPA 或 MPA 的页面切换场景下,我们可以这样理解:
- SPA 路由切换:每次切换相当于一次「迷你加载」。LCP 对应新页面的最大元素,FID 对应切换后用户首次操作,CLS 对应切换过程中的布局偏移。
- MPA 页面跳转:每次跳转就是一次完整加载,直接套用 Web Vitals 标准。
我的经验: 在优化一个电商 App 的「商品详情页 → 购物车」切换时,我发现 CLS 从 0.05 飙升到 0.35。原因是购物车列表加载时,图片没有预留宽高,导致文字先渲染,图片加载后把文字挤下去了。用户反馈「点加入购物车后页面乱跳」——这就是 CLS 在作祟。
3.3 用工具测量页面切换的 Web Vitals
光知道概念没用,得能测出来。我推荐三种方式:
3.3.1 使用 Performance Observer API
这是最精确的方式,直接在代码里监听:
// 监听 LCP
const lcpObserver = new PerformanceObserver((list) => {
const entries = list.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP:', lastEntry.startTime, lastEntry.element);
});
lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true });
// 监听 FID
const fidObserver = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
console.log('FID:', entry.processingStart - entry.startTime);
});
});
fidObserver.observe({ type: 'first-input', buffered: true });
// 监听 CLS
let clsValue = 0;
const clsObserver = new PerformanceObserver((list) => {
list.getEntries().forEach((entry) => {
if (!entry.hadRecentInput) {
clsValue += entry.value;
}
});
console.log('CLS:', clsValue);
});
clsObserver.observe({ type: 'layout-shift', buffered: true });
performance.clearResourceTimings() 并重新创建观察者。否则你会拿到上一个页面的残留数据。
3.3.2 使用 web-vitals 库
不想手写?用 Google 官方库:
import { onLCP, onFID, onCLS } from 'web-vitals';
// 每次路由切换后重新调用
function reportPageSwitchMetrics() {
onLCP(console.log, { reportAllChanges: true });
onFID(console.log);
onCLS(console.log, { reportAllChanges: true });
}
// 在路由切换完成时调用
router.afterEach(() => {
reportPageSwitchMetrics();
});
3.3.3 使用 Chrome 开发者工具
快速验证时,我直接用 DevTools 的 Performance 面板,勾选「Web Vitals」:
- 打开 DevTools → Performance
- 点击「录制」按钮旁边的齿轮图标
- 勾选「Web Vitals」
- 录制一次页面切换
- 在 Timeline 上会看到 LCP、FID、CLS 的标记点
3.4 知识体系:页面切换性能分析工具全景
下面这张图是我自己梳理的,把今天讲的内容串起来:
3.5 实战建议:如何用这套工具链
最后,我分享一个自己常用的工作流:
- 开发阶段:每次提交前跑一次 Lighthouse 模拟模式,关注 LCP 和 TBT 的变化趋势。如果 LCP 增加超过 0.5s,我会停下来排查。
- 联调阶段:用 DevTools 的 Performance 面板录制真实页面切换,结合 Web Vitals 标记点定位具体瓶颈。
- 上线前:在预发布环境用 Lighthouse 真实模式跑一遍,确保所有指标在「良好」范围内。
- 线上监控:接入 web-vitals 库,上报到监控平台。设置告警:LCP > 3.0s 或 CLS > 0.2 时自动通知。
好了,这一讲的内容就到这里。工具是死的,场景是活的。下次遇到页面切换卡顿,先别急着改代码,用 Lighthouse 和 Web Vitals 把「病根」找出来,再对症下药。