PerformanceFrontend2024 Edition

Core Web Vitals
深度解析

Web Vitals 是 Google 提出的统一质量信号,旨在简化并量化影响用户体验的方方面面。 本文将带你从 LCP、INP、CLS 三大核心指标出发,逐层剖析整个前端性能指标体系。

≤2.5s
Good

LCP

Largest Contentful Paint

最大内容绘制时间

≤200ms
Good

INP

Interaction to Next Paint

交互到下一帧绘制

≤0.1
Good

CLS

Cumulative Layout Shift

累计布局偏移

Why It Matters

为什么 Web Vitals 至关重要?

Google 已将 Core Web Vitals 作为搜索排名因素之一。性能不仅影响 SEO, 更直接决定用户留存率和转化率。每一毫秒都至关重要。

+24%

跳出率降低(满足 CWV)

排名因素

直接影响 Google SEO

53%

移动端用户3s内离开

全球标准

Chrome UX Report 真实数据

Core Metrics Deep Dive

三大核心指标深度剖析

LCP — Largest Contentful Paint

最大内容绘制 · 衡量加载性能

≤2.5s
Good
≤4.0s
Needs Work
>4.0s
Poor

LCP 测量视口中最大可见内容元素(图片、视频海报、大块文本)完成渲染的时间点。 它反映了用户感知到页面主体内容可用的时刻。不同于 FCP,LCP 专注于「关键内容」而非任意像素。

📌 LCP 候选元素

<img> 元素
<image> 内 SVG <image>
<video> 海报帧
background-image (通过 url())
包含文本节点的块级元素

🚀 优化策略

优化服务端响应时间 (TTFB < 800ms)
使用现代图片格式 (WebP/AVIF) + 响应式尺寸
关键资源预加载 <link rel='preload'>
消除渲染阻塞资源 (inline 关键 CSS)
CDN 边缘缓存 + Service Worker 策略
避免客户端渲染 LCP 元素 (优先 SSR/SSG)

INP — Interaction to Next Paint

交互到下一帧绘制 · 衡量交互响应性(2024年取代 FID)

≤200ms
Good
≤500ms
Needs Work
>500ms
Poor

INP 通过观察用户在页面停留期间所有点击、键盘输入和触摸交互的延迟, 选取最差交互延迟(高百分位数)作为最终评分。它全面评估页面的整体响应能力, 而不仅仅是最差的第一次交互(这是 FID 的局限)。

⏱️ INP 的三个阶段

1

Input Delay

输入延迟

主线程忙?

2

Processing

事件处理

JS 执行耗时

3

Presentation

帧呈现延迟

DOM 更新 + 渲染

🚀 优化策略

拆分长任务 (Long Tasks > 50ms → scheduler.yield)
减少主线程工作 (代码分割 + 懒加载)
避免强制同步布局 (读写分离 DOM 属性)
使用 requestIdleCallback 调度低优先级任务
Web Worker 卸载重计算逻辑
减少 DOM 节点数量 (虚拟列表)

CLS — Cumulative Layout Shift

累计布局偏移 · 衡量视觉稳定性

≤0.1
Good
≤0.25
Needs Work
>0.25
Poor

CLS 测量页面整个生命周期中所有非用户触发的意外布局偏移的累计分数。 高 CLS 意味着页面元素在加载过程中不断跳动,严重破坏用户体验。 其计算公式为 影响分数 × 距离分数

影响区域

不稳定元素影响视口面积占比

移动距离

元素在两帧之间移动的最大距离

CLS 分数

= 影响区域 × 移动距离 (累加)

常见 CLS 罪魁祸首

未指定尺寸的图片/视频

异步加载的 Web 字体 (FOIT/FOUT)

动态注入的内容(广告、弹窗)

动态调整大小的元素

在已有内容上方插入 DOM

修复方案

始终设置 width/height 属性或 aspect-ratio

font-display: swap + 预加载关键字体

为动态内容预留空间 (min-height)

使用 CSS contain 属性隔离布局

使用 transform 动画替代改变几何属性

Supporting Metrics

其他重要指标

除了三大核心指标,还有几个关键的辅助指标帮助诊断性能瓶颈。

≤1.8s

FCP

First Contentful Paint

首次内容绘制:浏览器渲染第一个 DOM 内容的时间。LCP 之前的“先行者”。

≤800ms

TTFB

Time to First Byte

首字节时间:请求发出到接收第一个字节的耗时。反映服务器响应速度。

≤3.4s

SI

Speed Index

速度指数:页面可视区域内容填充速度的综合指标,基于视频帧分析。

≤200ms

TBT

Total Blocking Time

总阻塞时间:FCP 到 TTI 之间所有长任务 (>50ms) 超出部分的总和。

≤3.8s

TTI

Time to Interactive

可交互时间:页面完全可响应用户输入的时刻(长任务 ≤50ms)。

→ INP

FID ⚠️

First Input Delay (已弃用)

首次输入延迟:已于 2024 年 3 月被 INP 正式取代,仅衡量首次交互。

Measurement Tools

测量工具全景

性能优化始于精确的测量。了解实验室数据与真实用户数据 (RUM) 的区别至关重要。

Lab Data · 实验室数据

模拟环境测试

Lighthouse

Chrome 内置,综合审计评分 + 优化建议

CLI / DevTools

PageSpeed Insights

结合 Lighthouse + CrUX 真实数据

Web 工具

WebPageTest

多地点、多设备的瀑布流分析

高级诊断

Chrome DevTools

Performance 面板逐帧分析

开发者
Field Data · 真实数据

用户真实体验

CrUX

Chrome 用户体验报告

web-vitals JS

npm 库,实时 RUM

GTMetrix

综合监控面板

Code Example

实战:接入 web-vitals

使用 web-vitals 库在应用中收集真实用户指标并上报。

lib/web-vitals.ts
import { onLCP, onINP, onCLS, onFCP, onTTFB } from "web-vitals";

type MetricPayload = {
  name: string;
  value: number;
  rating: "good" | "needs-improvement" | "poor";
  id: string;
  delta: number;
  navigationType: string;
};

function sendToAnalytics(metric: MetricPayload) {
  // 上报到你的分析平台
  const body = JSON.stringify({
    ...metric,
    page: window.location.pathname,
    userAgent: navigator.userAgent,
    timestamp: Date.now(),
  });

  // 使用 sendBeacon 确保页面关闭前也能发送
  if (navigator.sendBeacon) {
    navigator.sendBeacon("/api/vitals", body);
  } else {
    fetch("/api/vitals", { body, method: "POST", keepalive: true });
  }
}

export function initWebVitals() {
  onLCP(sendToAnalytics);   // 最大内容绘制
  onINP(sendToAnalytics);   // 交互到下一帧绘制
  onCLS(sendToAnalytics);   // 累计布局偏移
  onFCP(sendToAnalytics);   // 首次内容绘制
  onTTFB(sendToAnalytics);  // 首字节时间
}
Optimization Checklist

性能优化全栈清单

加载性能

渲染性能

JS 运行时

网络与基础设施

影响 TTFB

性能即用户体验

记住核心目标:LCP ≤ 2.5s · INP ≤ 200ms · CLS ≤ 0.1。 持续监测、渐进优化、用数据驱动决策 —— 让每一毫秒都成为竞争优势。