← 返回专栏
· 3 分钟阅读

核心网页指标详解:免费工具提升页面速度

页面速度是谷歌确认的排名因素。本文教你只用免费工具测量和优化核心网页指标(LCP、INP、CLS),不用Ahrefs,不用付费审计。

Google 早就说得很清楚了:页面加载速度影响排名。虽然不像内容相关性那么重,但页面太慢确实会拖累本来不错的内容。好消息是,测量和修复页面速度的工具全都免费。你不需要 Ahrefs,不需要付费的站点审计工具,更不需要每个月 500 美元的企级平台来告诉你图片太大了。

这篇文章会讲清楚 Core Web Vitals 是什么、怎么免费测量,以及哪些优化真正有效。

Core Web Vitals 到底在量什么

Google 通过三个指标评估页面体验。截至 2024 年,这组指标是:

LCP(最大内容绘制) —— 页面上最大的可见元素渲染出来需要多久。通常是一张图片、一个 Hero 区域,或者一大块文本。LCP 元素就是用户第一眼看到的最大东西。如果超过 2.5 秒才出现,Google 会把你的页面标记为“需要改进”。超过 4 秒就是“较差”。

INP(下一次绘制的交互延迟) —— 2024 年 3 月取代了 FID。衡量的是用户点击、触摸或打字时页面响应有多快。它捕捉的是完整的交互延迟——从输入到下一次视觉变化。低于 200ms 算好。超过 500ms 算差。INP 比 FID 更难优化,因为它测的是最差情况下的交互,不只是第一次交互。

CLS(累积布局偏移) —— 页面加载过程中布局偏移了多少。你应该经历过:想点一个链接,但上面加载了一张图片把链接挤下去了。低于 0.1 算好。超过 0.25 算差。

指标良好需要改进较差
LCP< 2.5s2.5s - 4.0s> 4.0s
INP< 200ms200ms - 500ms> 500ms
CLS< 0.10.1 - 0.25> 0.25

这三个指标都是通过 Chrome 用户体验报告(CrUX)基于真实用户数据测量的,不是合成实验室测试。这个区别很重要——你会看到不同的数字,取决于你是在看现场数据(真实用户)还是实验室数据(模拟)。

免费测量 Core Web Vitals 的工具

PageSpeed Insights(PSI)

检查任何页面最快的方法。打开 pagespeed.web.dev,粘贴你的 URL,就能同时看到实验室数据(Lighthouse 模拟)和现场数据(真实 Chrome 用户)。

实验室数据告诉你技术上出了什么问题。现场数据告诉你真实用户实际体验如何。如果实验室 LCP 是 1.8s,但现场 LCP 是 3.5s,说明在较慢设备和网络上的真实用户体验比你的测试环境显示的更差。

永远优先看现场数据,而不是实验室数据。 因为 Google 排名用的是现场数据。

Google Search Console

GSC 有专门的 Core Web Vitals 报告。它会显示哪些 URL 分组达标、哪些需要改进、哪些较差——基于你整个站点的真实用户数据汇总。

这份报告最实用,因为它按模板对 URL 分组。如果你的 /blog/ 页面 LCP 都很差,修好博客布局模板就能一次性解决所有博客页面。

想全面了解 GSC 还能为你的 SEO 做什么,看看我们的 Google Search Console 指南

Chrome DevTools(web-vitals 库)

在本地开发时想要最精确的测量,安装 Google 的 web-vitals 库:

npm install web-vitals

然后把它加到你的应用里:

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

onLCP(console.log);
onINP(console.log);
onCLS(console.log);

打开 Chrome DevTools,导航到你的页面,看控制台输出。你会得到带归因的精确指标值——是哪个元素导致 LCP 偏慢,哪次交互让 INP 变慢,哪些布局偏移贡献了 CLS。

Lighthouse CLI

如果你想在 CI 或批量场景中审计多个页面:

npm install -g lighthouse
lighthouse https://example.com --output=json --output-path=./report.json

Lighthouse 给你实验室数据和完整的审计清单——每一条优化机会、诊断、通过的审计,都附有具体建议。

修复 LCP(最大内容绘制)

LCP 太慢几乎总是三个原因之一:图片太大、服务器响应慢、或者渲染阻塞资源。

优化图片

图片是 LCP 不达标的头号原因。一张全分辨率 PNG 格式的 3MB Hero 图,不管服务器多快都会拖垮你的 LCP。

使用现代格式。 WebP 和 AVIF 比 JPEG/PNG 小 25-50%,视觉质量没有明显损失。所有现代浏览器都支持 WebP。AVIF 在 Chrome、Firefox 和 Safari 16+ 中受支持。

设置显式尺寸。 如果你的 LCP 图片没有 widthheight 属性(或 CSS aspect-ratio),浏览器无法为它预留空间。浏览器会下载图片、重新计算布局、把所有内容挤下去——LCP 和 CLS 一起崩。

<!-- 不推荐:没有尺寸 -->
<img src="hero.jpg" alt="Hero">

<!-- 推荐:显式尺寸 -->
<img src="hero.webp" width="1200" height="630" alt="Hero" fetchpriority="high">

在 LCP 图片上使用 fetchpriority="high" 这会告诉浏览器优先下载它,而不是其他资源。所有现代浏览器都支持。

对首屏以下的图片做懒加载。 不要让浏览器下载用户还看不到的图片:

<img src="below-fold.webp" loading="lazy" width="800" height="600" alt="...">

提供响应式图片。 不要把 2400px 的图片发给手机。用 srcset

<img
  src="hero-800.webp"
  srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
  sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
  width="1200" height="630"
  alt="Hero"
  fetchpriority="high"
>

降低服务器响应时间(TTFB)

你的首字节时间影响下游一切环节。如果服务器需要 800ms 才响应,你的 LCP 下限在渲染开始之前就已经是 800ms 了。

使用 CDN。 Cloudflare、BunnyCDN 或任何边缘网络都能大幅降低 TTFB,因为内容从离用户更近的位置返回。如果你在用 Cloudflare Pages、Vercel 或 Netlify,你已经有 CDN 了。

积极设置缓存。 设置合适的 Cache-Control 头。静态资源应该缓存一年:

Cache-Control: public, max-age=31536000, immutable

HTML 页面应该用更短的缓存时间或重新验证:

Cache-Control: public, max-age=0, must-revalidate

用 SSR 或 SSG,不要用 CSR。 客户端渲染意味着浏览器要下载 JavaScript、解析、执行,然后才能渲染内容。服务端渲染或静态站点生成会立即发送预渲染的 HTML。对内容型网站来说,没有理由用 CSR。Astro 这类框架默认就输出零 JS 的静态 HTML。

消除渲染阻塞资源

<head> 里的 CSS 和 JavaScript 会阻塞渲染。浏览器在下载并解析这些文件之前无法绘制任何内容。

内联关键 CSS。 提取首屏内容所需的 CSS,直接内联到 <style> 标签里。其余部分延迟加载。critters(用于 Webpack)或 Astro 内置的 CSS 处理会自动做这件事。

延迟非关键 JavaScript。 任何初始渲染不需要的 <script> 都应该加 deferasync

<script src="analytics.js" defer></script>
<script src="chat-widget.js" async></script>

defer 会并行下载脚本,但等 HTML 解析完才执行。async 也是并行下载,但下载完就立即执行。大多数分析和跟踪脚本用 defer

修复 INP(下一次绘制的交互延迟)

INP 衡量的是对用户输入的响应能力。INP 慢通常意味着 JavaScript 在用户尝试交互时阻塞了主线程。

拆分长任务

任何运行时间超过 50ms 的 JavaScript 任务都是“长任务”。在这期间,页面是无响应的。长任务期间的点击会被排队,感觉特别卡。

// 不推荐:阻塞主线程
function processItems(items) {
  items.forEach(item => {
    heavyComputation(item);
  });
}

// 更好:让出主线程
async function processItems(items) {
  for (const item of items) {
    heavyComputation(item);
    await scheduler.yield(); // 让浏览器处理输入
  }
}

scheduler.yield() 在 Chrome 129+ 可用。要支持更多浏览器,用 setTimeout

function yieldToMain() {
  return new Promise(resolve => setTimeout(resolve, 0));
}

减小 JavaScript 包体积

每一千字节的 JavaScript 都需要下载、解析和执行。一个 500KB 的 JS 包在中端手机上能造成 300-500ms 的主线程阻塞。

代码拆分。 只在需要的页面上加载对应的 JavaScript。基于路由的代码拆分意味着你的博客页面不会加载定价页面的 JavaScript。

审查第三方脚本。 分析工具、聊天组件、热力图、广告像素——每一样都在往页面上加 JavaScript。跑一下 Lighthouse,看“Reduce JavaScript execution time”审计项。你能看到每个脚本的影响明细。

能用 CSS 就不用 JavaScript。 动画、下拉菜单、手风琴,能用 CSS 实现的就不需要 JavaScript。CSS 在合成器线程上运行,永远不会阻塞主线程。

requestIdleCallback 处理非紧急任务

// 延迟分析和遥测
requestIdleCallback(() => {
  sendAnalytics();
});

这告诉浏览器“等你有空再干这个”。它能保持面向用户的交互保持响应。

修复 CLS(累积布局偏移)

CLS 是最容易修复的 Core Web Vital。布局偏移发生在页面开始渲染后元素发生移动的时候。

总是给图片和嵌入内容设置尺寸

<!-- 这会导致布局偏移 -->
<img src="photo.jpg" alt="Photo">

<!-- 这不会 -->
<img src="photo.webp" width="800" height="600" alt="Photo">

没有尺寸的话,浏览器不知道要预留多少空间。它先渲染文字,然后图片加载出来把一切都挤下去。

为广告和嵌入内容预留空间

如果你有广告位、YouTube 嵌入或第三方组件,在内容加载前用 CSS min-heightaspect-ratio 预留空间:

.ad-slot {
  min-height: 250px;
}

.video-embed {
  aspect-ratio: 16 / 9;
}

不要在已有内容上方注入新内容

横幅、Cookie 通知和“订阅我们 newsletter”弹窗会把内容往下挤,导致布局偏移。如果一定要用:

  • position: fixedposition: sticky,让它们覆盖内容而不是推开内容
  • 在动态内容加载前用 CSS 预留空间
  • transform 做动画,而不是改 heighttop

避免 Web 字体导致的布局偏移

在初始渲染之后加载的自定义字体会导致文本回流——先渲染系统字体,然后自定义字体以不同的度量指标替换进来。

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter.woff2') format('woff2');
  font-display: swap;
}

font-display: swap 告诉浏览器立即用回退字体渲染文本,等自定义字体加载完再换上。为了尽量减少偏移,选择一个度量指标(大小、x-height、字间距)相近的回退字体。

想要更好的效果,在 @font-face 里用 size-adjust 让回退字体的度量指标更匹配:

@font-face {
  font-family: 'Inter Fallback';
  src: local('Arial');
  size-adjust: 100.5%;
  ascent-override: 92%;
  descent-override: 22%;
}

移动端性能才是关键

Google 使用移动优先索引和移动端 CrUX 数据来排名。你的桌面端分数几乎无关紧要。一个在你的 MacBook 上 1.2s 就能加载完的页面,在 4G 网络下的中端 Android 手机上可能要 4.5s。

测试时一定要模拟移动端限速。 在 Chrome DevTools 里打开 Performance 面板,把网络设为“Slow 4G”,CPU 设为“4x slowdown”。这模拟的是真实的移动体验。

看 PSI 的移动端标签,不是桌面端。 如果移动端分数是绿色,那就没问题。如果不是,桌面端分数再高也没用。

Core Web Vitals 和其他 SEO 工作的关系

Core Web Vitals 不是孤立存在的。它们是技术 SEO 基础的一部分:

  • 快的页面爬取效率更高——Googlebot 有爬取预算,慢页面会消耗更多预算
  • 好的页面体验和优质内容是叠加效应——Google 会奖励既相关又快的页面
  • Schema 标记和 Core Web Vitals 一起构成了技术上优化的页面,搜索引擎和用户都喜欢
  • 跑一次技术 SEO 审计,除了速度之外还能发现其他问题——死链、缺失 canonical、爬取错误

持续监控 Core Web Vitals

修复 Core Web Vitals 不是一次性任务。随着你添加内容、安装新工具、改版布局,分数会不断波动。

设置 GSC 提醒。 Google Search Console 里的 Core Web Vitals 报告每周更新。定期检查是否有新的 URL 分组出现回退。

接入 CI 管道。 每次部署都跑一次 Lighthouse,分数低于阈值就构建失败:

lighthouse https://staging.example.com \
  --only-categories=performance \
  --budget-path=./lighthouse-budget.json \
  --output=json --output-path=./lh-report.json

在生产环境中使用 web-vitals 库。 把真实用户指标发送到你的分析系统:

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

function sendToAnalytics({ name, value, rating }) {
  navigator.sendBeacon('/api/vitals', JSON.stringify({ name, value, rating }));
}

onLCP(sendToAnalytics);
onINP(sendToAnalytics);
onCLS(sendToAnalytics);

这样你能获得每个页面的现场数据,而不只是 CrUX 报告的数据。

快速见效清单

大部分 Core Web Vitals 的改进来自几项简单的改动:

  • 把所有图片转成 WebP 或 AVIF
  • 给每个 <img> 标签加上 widthheight
  • 给 LCP 图片加上 fetchpriority="high"
  • 给首屏以下的图片加上 loading="lazy"
  • 给所有非关键 <script> 标签加 defer
  • 给静态资源设置 Cache-Control
  • 自定义字体上用 font-display: swap
  • min-heightaspect-ratio 为广告和嵌入内容预留空间
  • 移除未使用的 JavaScript(跑 Lighthouse 的“Reduce JavaScript execution time”审计)
  • 用 PSI 测试移动端性能

从图片开始——对大多数站点来说,这是 LCP 最大的一项改进。然后处理 JavaScript。CLS 修复又快又稳。对典型内容站点来说,整个过程花 2-4 小时就能搞定,而且每项改进都会在所有共用同一模板的页面上叠加生效。

想给自己的站点做同样的分析?

ZensInk Pro 把这个流程自动化了。一条命令,从种子词到内容计划。

查看 Pro →