性能优化简介

性能指标与 Lighthouse

掌握 Web Vitals 核心性能指标,学会使用 Lighthouse 分析和评估页面性能。

🎯 引言

这是「性能优化」课程的最后一篇。前面几篇我们学了不少优化手段:懒加载、防抖节流、缓存策略、构建瘦身。但有一个问题始终没回答:优化做完了,怎么证明它真的有效?

凭感觉说「好像快了一点」是没有说服力的。学完本篇,你将能看懂 Web Vitals 这套业界通用的性能指标,会用 Chrome 自带的 Lighthouse 给页面跑分、读懂它的诊断建议,还能用 Performance 面板定位让页面卡顿的长任务。从此你的每一次优化,都有数据作证。


🧱 为什么要量化:用数据说话

先看一个常见场景。你花了两天时间给首页做了图片懒加载,跟老板说「页面快多了」。老板问:快了多少?你答不上来,这两天的价值就打了折扣。

性能优化的完整闭环应该是:先测量出基线数据,再做优化,最后重新测量对比。没有第一步的基线,第三步的对比就无从谈起。而且凭感觉的优化很容易方向错误:你以为瓶颈在图片,实际可能是某段同步 JS 阻塞了渲染。

量化还能帮你统一团队语言。大家约定好「LCP 要控制在 2.5 秒以内」,比各自说「我觉得挺流畅」清晰得多。接下来就认识这套通用语言:Web Vitals。


⚖️ Web Vitals 核心指标

Web Vitals 是 Google 公布的一套页面体验衡量标准,其中三个核心指标(Core Web Vitals)分别对应用户体验的三个维度:加载快不快、响应跟不跟手、画面稳不稳。下面逐个来看,它们的标准都是公开可查的客观事实。

LCP:加载快不快

LCP(Largest Contentful Paint,最大内容绘制):页面主要内容加载完成的时间点,简单说就是「屏幕上那块显眼的区域(通常是首屏大图或大标题)什么时候画出来」。良好标准是 ≤ 2.5 秒

可以把打开网页想象成进餐厅吃饭:LCP 就是「主菜端上桌」的时刻。顾客不关心厨房什么时候开始备菜,只关心主菜什么时候能吃上。

LCP 偏慢,常见优化方向是减少首屏资源的体积和数量,比如图片压缩与懒加载、关键资源预加载,这些在《加载优化》一篇里已经讲过。

INP:响应跟不跟手

INP(Interaction to Next Paint,交互到下一次绘制):从用户点击、输入到页面给出视觉反馈的耗时,衡量页面交互的响应速度。良好标准是 ≤ 200 毫秒

继续用餐厅比喻:INP 就是你举手叫服务员,对方多久做出反应。超过 200 毫秒,用户就会觉得「这页面是不是卡住了」。

INP 偏高,通常意味着主线程被长任务占住了,常见优化方向是拆分耗时任务、给高频事件加防抖节流,对应《渲染优化》一篇的内容。

CLS:画面稳不稳

CLS(Cumulative Layout Shift,累积布局偏移):页面加载过程中元素意外移动的累计幅度,衡量视觉稳定性。良好标准是 ≤ 0.1(它是一个无单位的分数,不是时间)。

你一定遇到过这种体验:刚想点一个按钮,图片加载完成把按钮挤下去了,结果点到了广告。这就是 CLS 在作怪,像吃饭时桌子突然晃了一下。

CLS 偏高,常见优化方向是给图片和广告位提前写好宽高占位、避免在已有内容上方插入新元素。

除了三大核心指标,还有两个常见的参考指标:FCP(首次内容绘制,屏幕第一次出现内容的时刻)和 TTFB(首字节时间,服务器响应的快慢)。它们不参与核心考核,但能帮你定位问题出在服务器还是页面渲染。

🛠 使用 Lighthouse 给页面跑分

指标的标准清楚了,那我的页面到底得多少分?不用装任何软件,Chrome 浏览器自带的 Lighthouse 就能告诉你。

Chrome DevTools 的界面会不定期更新,面板名称和入口位置可能与你看到的略有不同。以下流程仅供参考,核心思路不变,操作时以你浏览器里的实际页面为准。

打开你要检测的页面,按 F12 打开开发者工具,切换到 Lighthouse 面板,然后:

  1. 在 Categories(类目)中勾选 Performance,其他类目(无障碍、SEO 等)可以先不勾,让报告更聚焦。
  2. 设备选择 Mobile(移动端评分更严格,更接近真实用户的弱网环境)。
  3. 点击 Analyze page load,等待几十秒,报告就出来了。
建议在无痕窗口中跑分。浏览器插件会注入脚本干扰结果,无痕模式默认不加载插件,数据更干净。

看懂 Performance 分数

报告顶部是一个 0 到 100 的综合分数:90 到 100 为良好(绿色),50 到 89 为需要改进(橙色),0 到 49 为较差(红色)。这个分数由 LCP、INP、CLS、FCP 等指标加权得出,所以分数下面会列出每个指标的具体数值,方便你定位是哪一项拖了后腿。

看懂诊断建议

继续往下翻,有两个板块值得重点看:

  • Opportunities(优化机会):列出可以直接动手改进的点,比如「压缩图片」「移除阻塞渲染的资源」,每条还会估算可能节省的时间。
  • Diagnostics(诊断):更深入的分析,比如主线程耗时分布、过长的 JavaScript 执行时间,帮你理解分数背后的原因。

读报告的正确姿势是:先看指标数值找到短板,再看 Opportunities 里对应的建议。分数本身只是参考,真正的价值在于它告诉你下一步该优化哪里。另外,Lighthouse 测的是你自己电脑上的一次访问,属于「实验室数据」,和真实用户的体验可能有出入,这一点我们在后面还会提到。


🧰 Performance 面板:定位长任务

Lighthouse 告诉你「响应慢」,但具体慢在哪段代码?这就要请出 Chrome DevTools 的另一个面板:Performance

打开 Performance 面板,点击录制按钮,然后在页面上做几个典型操作(比如滚动列表、点击按钮),再停止录制。你会得到一条主线程的时间线,上面每个色块代表一段任务。重点关注那些耗时超过 50 毫秒的任务,它们被称为长任务(Long Tasks),在面板里会标上红色的角标。长任务会霸占主线程,让用户的点击得不到及时响应,正是 INP 偏高的常见元凶。

点开一个长任务,你可以看到它由哪些函数调用组成,顺着调用栈找到耗时的源头代码。接下来就可以对症下药:是循环太重就拆分任务,是事件触发太频繁就加防抖节流。这些手段在《渲染优化》一篇里都有详细讲解,现在你知道该在什么时候把它们用上了。


💡 在真实用户环境采集指标

Lighthouse 跑分有一个天然局限:它测的是你这台电脑、这条网络下的表现。而真实用户分布在各种设备和网络环境里,体验可能完全不同。想在真实用户环境中采集 Web Vitals 数据,可以使用 Google 官方的 web-vitals 这个 npm 包。

以下示例在 Node.js v22、web-vitals v5.x 环境下验证,安装命令如下:

# 本地 Node.js 版本:v22,包版本:web-vitals v5.x
pnpm add web-vitals

然后在项目入口文件中采集三个核心指标:

main.js
import { onLCP, onINP, onCLS } from 'web-vitals';

// 每个回调会在对应指标确定时触发,metric.value 就是指标数值
onLCP((metric) => {
    console.log('LCP:', metric.value);
});

onINP((metric) => {
    console.log('INP:', metric.value);
});

onCLS((metric) => {
    console.log('CLS:', metric.value);
});

实际项目里,你可以把 console.log 换成上报逻辑,把数据发送到自己的统计接口,持续观察线上用户的真实体验。这里了解用法即可,不需要现在就搭一套上报系统。


⚡ 性能优化是一个循环

到这里,本课程的内容就完整了。回顾一下这五篇的主线:

  1. 性能优化概览:建立整体认识,知道优化从加载、渲染、缓存、构建、指标五个方向入手。
  2. 加载优化:让资源更快到达浏览器,比如懒加载、预加载、代码分包。
  3. 渲染优化:让页面跑起来不卡顿,比如防抖节流、虚拟列表。
  4. 缓存策略:让二次访问接近瞬时加载,比如强缓存与协商缓存。
  5. 构建产物优化:从源头给资源瘦身,比如体积分析与 tree shaking。

而这篇讲的是把它们串起来的那根线:测量 → 优化 → 验证。先用 Web Vitals 和 Lighthouse 测量,找到短板;再用前面几篇的手段针对性优化;最后重新测量,确认数据真的改善了。一次循环结束,再开始下一轮。性能优化没有「一劳永逸」的终点,跟着数据一轮轮迭代,才是正确的工作方式。


🧾 小节总结

  • 性能优化要用数据说话:先测量基线,再优化,最后重新测量对比,形成完整闭环。
  • Web Vitals 三大核心指标:LCP 衡量加载(良好标准 ≤ 2.5 秒)、INP 衡量交互响应(良好标准 ≤ 200 毫秒)、CLS 衡量视觉稳定性(良好标准 ≤ 0.1),FCP 和 TTFB 可作为参考。
  • Lighthouse 在 Chrome DevTools 中直接使用,重点看 Performance 分数、各指标数值,以及 Opportunities 和 Diagnostics 给出的优化建议。
  • Performance 面板可以录制页面运行过程,通过查找标红的长任务(超过 50 毫秒)定位卡顿的源头代码。
  • web-vitals 包可以在真实用户环境中采集指标,弥补 Lighthouse「实验室数据」的局限。
  • 性能优化是「测量 → 优化 → 验证」的持续循环,本课程前五篇的优化手段就是循环中「优化」这一步的工具箱。

❓ 知识问答

Q1:Lighthouse 跑出来的分数,每次都不一样,正常吗?

A:正常。跑分受当前电脑负载、网络波动影响,小幅浮动是常见现象。建议多跑几次取趋势,重点看指标量级而不是纠结一两分的差别。

Q2:LCP、INP、CLS 三个指标,应该先优化哪个?

A:先看哪个没达到良好标准,没达标的优先。都达标后再看哪个离标准线近、优化成本低。不要凭喜好挑,跟着数据走。

Q3:我在本地跑 Lighthouse 分数很高,是不是就没问题了?

A:不一定。本地环境通常设备和网络都比较好,真实用户的情况更复杂。本地高分说明基础不错,但要确认真实体验,还需要用 web-vitals 这类工具采集线上数据。

Q4:超过 50 毫秒的任务都算问题吗?

A:长任务是一个提醒信号,不是说每个都必须消灭。先看它是否出现在用户交互的关键路径上:如果用户点击时主线程正好被长任务占住,INP 就会受影响,这种才需要优先处理。

Q5:这些指标和前面几篇的优化手段是什么关系?

A:指标是「体检报告」,优化手段是「药方」。比如 LCP 慢对应加载优化和构建产物优化,INP 高对应渲染优化,缓存策略则改善二次访问的加载速度。先诊断,再开方。


🧪 小练习

练习一:给页面跑一次体检。 选一个你做过的项目页面,用无痕窗口在 DevTools 的 Lighthouse 面板跑一次 Performance 检测。记录下 LCP、INP、CLS 三个数值,对照良好标准,写下你认为该优先优化的一项和理由。

练习二:接入 web-vitals 采集。 在一个本地项目中安装 web-vitals(Node.js v22、web-vitals v5.x),补全下面的代码,让三个指标触发时打印出中文标签和保留整数后的数值:

main.js
import { onLCP, onINP, onCLS } from 'web-vitals';

// 请在这里编写代码:用 onLCP 打印 LCP 数值,用 Math.round 取整

// 请在这里编写代码:用 onINP 打印 INP 数值,用 Math.round 取整

// 请在这里编写代码:用 onCLS 打印 CLS 数值(注意 CLS 是小数,可保留两位)

运行项目后打开控制台,操作一下页面(点击、滚动),观察三个指标的输出时机有什么不同。


🎉 恭喜你已经掌握性能指标与 Lighthouse 的使用啦!至此,性能优化课程全部完成。从今天起,让每一次优化都有数据作证,用「测量 → 优化 → 验证」的循环持续打磨你的页面吧!