Core Web Vitals 是 Google 衡量用户体验的核心指标,直接影响搜索排名。2026 年的指标体系已经稳定,INP(Interaction to Next Paint)正式替代 FID 成为主要的交互响应指标。
2026 年的核心指标
| 指标 | 缩写 | 良好 | 需改进 | 差 |
|---|---|---|---|---|
| Largest Contentful Paint | LCP | ≤2.5s | 2.5-4s | >4s |
| Interaction to Next Paint | INP | ≤200ms | 200-500ms | >500ms |
| Cumulative Layout Shift | CLS | ≤0.1 | 0.1-0.25 | >0.25 |
INP 替代 FID 的原因:
- FID 只测量首次输入延迟,忽略后续交互
- INP 测量所有交互的响应时间,更全面
- INP 包含了输入延迟、处理时间和渲染时间
LCP 优化
LCP 测量主要内容的加载时间:
html
<!-- 优化前 -->
<img src="hero.jpg" />
<!-- 优化后 -->
<img src="hero.jpg"
fetchpriority="high"
width="1200"
height="600"
alt="Hero image" />
LCP 优化策略:
策略 1:关键资源优先加载
html
<head>
<!-- 预连接 -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://cdn.example.com" />
<!-- 预加载关键资源 -->
<link rel="preload" href="/hero.jpg" as="image" />
<link rel="preload" href="/font.woff2" as="font" crossorigin />
</head>
策略 2:图片优化
html
<!-- 使用现代格式 -->
<picture>
<source srcset="hero.avif" type="image/avif" />
<source srcset="hero.webp" type="image/webp" />
<img src="hero.jpg" alt="Hero" />
</picture>
<!-- 响应式图片 -->
<img srcset="hero-400.jpg 400w, hero-800.jpg 800w, hero-1200.jpg 1200w"
sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
src="hero-800.jpg"
alt="Hero" />
策略 3:CSS 优化
css
/* 关键 CSS 内联 */
.hero {
background-image: url('/hero.jpg');
background-size: cover;
height: 100vh;
}
/* 非关键 CSS 异步加载 */
@media print {
.no-print { display: none; }
}
INP 优化
INP 测量交互响应时间,包括三个阶段:
javascript
// 1. 输入延迟(Input Delay)
// 从用户输入到事件处理器开始执行的时间
button.addEventListener('click', () => {
// 如果这里执行很慢,输入延迟会增加
});
// 2. 处理时间(Processing Time)
// 事件处理器执行的时间
function handleClick() {
// 复杂计算会增加处理时间
const result = heavyComputation();
}
// 3. 展示延迟(Presentation Delay)
// 从处理器执行完到下一帧渲染的时间
// 受布局、绘制、合成影响
INP 优化策略:
策略 1:减少主线程阻塞
javascript
// 不好的做法:同步长任务
function processLargeDataset(data) {
for (let i = 0; i < data.length; i++) {
heavyOperation(data[i]); // 阻塞主线程
}
}
// 好的做法:分块处理
async function processLargeDataset(data) {
const chunkSize = 100;
for (let i = 0; i < data.length; i += chunkSize) {
const chunk = data.slice(i, i + chunkSize);
chunk.forEach(item => heavyOperation(item));
// 让出主线程
await new Promise(resolve => setTimeout(resolve, 0));
}
}
策略 2:使用 Web Workers
javascript
// 主线程
const worker = new Worker('/worker.js');
worker.postMessage(largeDataset);
worker.onmessage = (e) => {
updateUI(e.data);
};
// Worker 线程
self.onmessage = (e) => {
const result = processData(e.data);
self.postMessage(result);
};
策略 3:优化事件处理器
javascript
// 不好的做法:每次点击都重新计算
button.addEventListener('click', () => {
const result = expensiveCalculation();
updateUI(result);
});
// 好的做法:防抖或节流
let timeout;
button.addEventListener('click', () => {
clearTimeout(timeout);
timeout = setTimeout(() => {
const result = expensiveCalculation();
updateUI(result);
}, 100);
});
CLS 优化
CLS 测量布局偏移,目标是保持稳定:
css
/* 为图片和广告预留空间 */
img, video {
max-width: 100%;
height: auto;
aspect-ratio: 16/9; /* 预留空间 */
}
/* 字体加载不影响布局 */
@font-face {
font-family: 'CustomFont';
src: url('/font.woff2') format('woff2');
font-display: swap; /* 使用备用字体,加载后替换 */
}
CLS 优化策略:
策略 1:设置尺寸
html
<img src="photo.jpg" width="800" height="600" alt="Photo" />
<iframe src="..." width="560" height="315"></iframe>
策略 2:避免动态插入内容
javascript
// 不好的做法:动态插入广告
const ad = document.createElement('div');
ad.innerHTML = '<img src="ad.jpg" />';
container.prepend(ad); // 推动下方内容
// 好的做法:预留空间
const ad = document.createElement('div');
ad.style.height = '250px'; // 预留空间
container.prepend(ad);
策略 3:使用 CSS containment
css
.sidebar {
contain: layout;
width: 300px;
}
测量工具
Chrome DevTools Performance 面板
录制性能并查看 INP 细节:
- 打开 Performance 面板
- 点击录制
- 进行交互操作
- 停止录制
- 查看 Interactions 部分
Lighthouse
bash
# 安装
npm install -g lighthouse
# 运行
lighthouse https://example.com --output=html
Web Vitals 库
javascript
import { onLCP, onINP, onCLS } from 'web-vitals';
function sendToAnalytics({ name, delta, id }) {
console.log(`${name}: ${delta} (${id})`);
}
onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);
监控与告警
生产环境的性能监控:
javascript
// 采集性能数据
if ('PerformanceObserver' in window) {
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.entryType === 'largest-contentful-paint') {
reportMetric('LCP', entry.startTime);
}
}
});
observer.observe({ entryTypes: ['largest-contentful-paint'] });
}
设置告警阈值:
- LCP > 2.5s:警告
- INP > 200ms:警告
- CLS > 0.1:警告
小结
Core Web Vitals 2026 的核心是 LCP、INP 和 CLS。LCP 优化关键资源加载,INP 优化交互响应,CLS 保持布局稳定。优化不是一次性工作,需要持续监控和改进。好的性能是用户体验的基础。
