LINNIL

提升网站性能:了解 Core Web Vitals 指标

Lucas

2025年4月14日
提升网站性能:了解 Core Web Vitals 指标

Core Web Vitals(核心网页指标)是 Google 推出的网页性能评估标准,涵盖了页面加载速度、交互响应能力以及视觉稳定性三大维度。 这些指标不仅反映了用户在真实设备上的体验感受,同时也被纳入 Google 搜索排名因素。 了解并优化 LCP、INP 和 CLS,能显著提升网站性能、用户满意度与 SEO 效果,是现代前端开发不可忽视的重要指标。

LCP(Largest Contentful Paint)

什么是 LCP ?

LCP 是衡量网页性能的一个关键指标,它评估了页面加载过程中 最大可视内容 的渲染时间。 简单来说, LCP 告诉我们用户第一次看到页面的主要内容(比如图片、文本块等)花费了多少时间。 这是用户体验中的一个重要环节,因为加载时间直接影响到用户的互动感受,如果 LCP 加载时间过长,用户可能会觉得页面响应迟缓,从而导致用户流失。 对于网站开发者来说,优化 LCP 使得网站快速呈现主要内容,能有效提高用户满意度并减少跳出率。

请务必注意, LCP 包括上一个网页的所有卸载时间、连接设置时间、重定向时间和其他 TTFB 延迟时间,这些时间在现场测量时可能会很长,并且可能会导致现场测量结果与实验室测量结果之间存在差异。

LCP 的测量规则

LCP 测量的是从页面开始加载到 最大的可视内容 完成绘制的时间。这个“最大内容”可以是:

  • 图片:例如页面的主图 <img> 元素,这也包括 svg 中的 image ,但是 <svg> 元素目前不被视为 LCP 候选元素。

  • 背景图像:作为页面设计的核心背景图片。url()

  • 视频元素:如果视频加载完毕,它也会被视为最大内容。<video>

  • 大块文本:例如页面中的主要标题或段落。

LCP 计算流程

众所周知网页的加载通常是分阶段的,因此网页上的最大元素也是会变化的,当有延迟加载的图片或者往 DOM 中添加了新元素时, LCP 候选元素会跟着变化。 但是当用户首次与页面互动时, LCP 观测器就会停止记录新元素,并返回最后一个最大元素的渲染时间。

具体流程如下:

  1. 页面开始加载(DOMContentLoaded 前):

    • 浏览器解析 HTML。

    • 构建 DOM。

    • 解析和应用 CSS。

    • 下载图片、字体、JS 等资源。

  2. 开始初次渲染(First Paint、FCP):

    • 页面背景颜色、HTML 框架渲染出来。

    • FCP(First Contentful Paint)记录第一个内容绘制时间(如文字、图像)。

  3. 收集 LCP 候选元素:

    • 浏览器在每次布局完成(Layout)后,扫描当前屏幕中可见的内容块;

    • 每当有 新内容 被绘制,或者已有内容被替换、尺寸变更,浏览器会更新 LCP 候选。

  4. 记录最大元素(面积最大者)及其 startTime:

    • 选取当前渲染的候选元素中面积最大的一个;

    • 若有新元素超越旧元素面积,将其替换为新的 LCP 候选。

  5. 用户首次交互(如点击、滚动、输入等)或页面隐藏时(如切换 Tab):

    • LCP 观测器自动停止;

    • 最后一个 LCP 候选的 startTime 被记录下来,即最终的 LCP 时间。

如果需要在 JS 中记录 LCP 时间,可以使用 PerformanceObserver 进行监听。

new PerformanceObserver((entryList) => {
  for (const entry of entryList.getEntries()) {
    console.log("LCP candidate:", entry.startTime, entry);
  }
}).observe({ type: "largest-contentful-paint", buffered: true });

理想的 LCP 时间

理想的 LCP 时间在2.5秒以内 理想的 LCP 时间在2.5秒以内

  • LCP < 2.5秒:优秀的加载体验,用户基本不会感受到加载延迟。

  • LCP 2.5秒到 4秒:可以接受,但可能会有部分用户流失。

  • LCP > 4秒:体验差,用户可能会放弃等待,直接跳出。

如何优化 LCP

概括来讲,优化 LCP 可分为以下四个步骤:

  1. 确保 LCP 资源尽早开始加载。
  2. 确保 LCP 元素可在其资源完成加载后立即渲染。
  3. 在不牺牲质量的情况下,尽可能缩短 LCP 资源的加载时间。
  4. 尽快提供初始 HTML 文档。

而 LCP 资源多为图片、视频,所以优化 LCP 也可以等价于优化你的资源文件,以下是一些建议:

  1. 优化图片和媒体资源:

    • 压缩图片 :通过压缩图片减少图片的加载时间。

    • 使用现代格式 :例如使用 WebP 格式代替 PNG 或 JPG 格式,它们具有更高的压缩比。

    • 懒加载(Lazy Loading) :对页面中的非关键资源(如图片、视频等)使用懒加载,避免它们阻塞页面的渲染。

    • 使用 CDN (内容分发网络) :将静态资源(如图片、CSS、JS 文件)托管在 CDN 上,缩短资源的加载时间。

  2. 优先加载关键 CSS 和 JavaScript:

    • CSS 优化:确保关键 CSS 被尽早加载,并且可以使用 Critical CSS 技术,将关键的 CSS 内联到 HTML 中,减少外部文件加载。(现代框架大多都支持自动化 Critical CSS 插件处理,所以你也许不需要这项优化)

    • 减少阻塞 JavaScript:使用 async 或 defer 属性来加载非关键的 JavaScript,避免阻塞页面渲染。

  3. 服务器端优化:

    • 提高服务器响应速度:优化服务器端的性能,减少页面渲染时的延迟。

    • 缓存机制:使用适当的缓存策略,减少不必要的请求,提升页面加载速度。

  4. 字体优化:

    • 使用 字体显示策略(font-display),如 font-display: swap,确保文本尽早显示,避免 FOUT(字体闪烁)。

INP

什么是 INP ?

INP (Interaction to Next Paint),即“用户交互到下一次绘制的时间”,用于衡量网页对用户操作的响应性能。专注于“点击、键盘操作、触摸”等交互,记录从用户发起操作到页面完成 视觉反馈 的时间。

INP 的测量规则

一个 INP 值的计算流程大致如下:

  1. 监听用户输入事件:如 keydown 、 click 等。

  2. 记录输入事件的开始时间。

  3. 记录浏览器开始“下一次绘制”的时间(也就是有明显视觉反馈的时候)。

  4. INP = 事件开始时间 → 到页面响应完成并绘制之间的时间差。

假设用户点击了一个按钮:时间触发时记录下时间,JS响应并执行花费了 150ms,浏览器开始绘制响应,那么这次交互的 INP 是:150ms

在一个页面中,用户可能触发多次交互。浏览器不会记录每一次,而是:记录 整段访问期间的所有交互事件响应时间 ,并最终取 响应时间最长的那次交互 , 或在多个交互中取代表性的一个作为最终 INP 值(排除偶发高延迟事件:会忽略每 50 次互动中的一次最高互动。)

理想的 INP 时间

理想的 INP 时间在200毫秒以内 理想的 INP 时间在200毫秒以内

  • INP ≤ 200ms:网页响应速度良好。

  • INP 200ms 到 500ms:网页的响应能力需要改进。

  • INP > 500ms:网页响应缓慢。

如何优化 INP

优化 INP 的关键是需要先确定互动速度缓慢的原因,最好是通过 Chrome的性能分析工具 来诊断和排查互动缓慢的问题,才能更好得对症下药。

以下是一些笼统的建议,具体还需要结合具体情况具体分析:

  1. 减少主线程阻塞:使用 requestIdleCallback 或 Web Worker 处理重计算任务。

  2. 避免大型任务堆积:使用 setTimeout(fn, 0) 或分块处理,利用 React 的 useTransition 等异步更新机制。

  3. 尽快提供视觉反馈:比如在按钮点击时先给个 loading 效果,再慢慢处理后续逻辑。

  4. 使用 CSS 动画替换 JS 动画:CSS 动画一般不会触发重排,可以提高渲染效率。

  5. 保持轻量的 DOM 结构和样式。

CLS

什么是 CLS ?

当你在页面中阅读一段文字,准备点击一个按钮。页面某个图片加载完成后,把按钮推下去导致你点错了。这就是“布局偏移”。意外的布局偏移可能会以多种方式干扰用户体验。

CLS 的测量规则

CLS 分数是该移动的两个测量值的乘积:影响百分比和距离百分比。

layout shift score = impact fraction * distance fraction

  1. 影响百分比(Impact Fraction):表示 受影响的可视区域比例 。当前可视区域 1000px 高,有 250px 的内容发生了位移,那影响分数是 0.25。

  2. 距离百分比(Distance Fraction):表示元素移动了 多少屏幕高度的比例 。按钮从 100px 跑到 300px,移动了 200px,如果屏幕高度是 800px,那么距离分数是 0.25。

CLS = Σ(影响分数 × 距离分数)

理想的 CLS 分数

理想的 CLS 分数应该 < 0.1 理想的 CLS 分数应该 < 0.1

  • CLS 0 ~ 0.1: 为了提供良好的用户体验,网站应尽力使 CLS 得分不高于 0.1。
  • CLS 0.1 ~ 0.25: 需要改进
  • CLS > 0.25: 较差

如何优化 CLS

导致 CLS 高的常见原因有以下这些:

  1. 没有尺寸的图片/视频/iframe。

  2. 动态注入的内容。

  3. 字体的加载。

优化思路也很明显:

  1. 为图片/视频/iframe 设置固定尺寸。

  2. font-display: swap。减少字体闪动。

  3. 对懒加载内容使用占位样式(Skeleton)。

  4. 减少在页面加载完成后又插入 DOM 的行为,或者使用动画过渡这一动作。

FCP

什么是 FCP ?

First Contentful Paint(首次内容绘制),是 Web Vitals 的核心指标之一,表示浏览器首次渲染“有内容”的 DOM 元素到屏幕的时间点,是衡量页面加载体验的关键指标。 简单来说就是当用户打开网页,屏幕上首次显示出任何文字、图片、SVG、canvas 等内容时,记录的时间点。

注意:显示出来的内容不能是纯背景色或空白,而是用户可见的实质性内容。

理想的 FCP 时间

理想的 FCP 应该 <  1.8 秒 理想的 FCP 应该 < 1.8 秒

  • FCP 0 ~ 1.8: 良好。
  • FCP 1.8 ~ 3.0: 需要改进
  • FCP > 3.0: 较差

如何优化 FCP

运行 Lighthouse 进行性能审核,并留意审核中建议的任何具体优化建议或诊断结果。

以下是一些导致 FCP 差的常见原因:

  1. 首屏 JavaScript 过大或阻塞渲染。

  2. 没有使用懒加载,加载了太多不必要的资源。

  3. 字体加载缓慢,页面空白等待字体。

  4. 服务端响应时间慢(TTFB 也影响)。

优化思路:

  1. 使用 SSR 或 SSG 提前渲染页面内容。

  2. 压缩 CSS/JS ,开启 gzipbrotli

  3. 使用 font-display: swap 加快字体展示。

  4. 避免 render-blocking 的脚本。

  5. 使用 preload 提前加载关键资源。

  6. 使用 CDN 提高资源加载速度。

TTFB

什么是 TTFB ?

Time to First Byte 表示浏览器从发出请求到接收到服务器返回的第一个字节所花费的时间。 简单来说就是用户访问网页时,浏览器向服务器发出请求,TTFB 就是从这个时刻起,到服务器开始响应、返回第一个字节给浏览器之间的这段时间。

用户点击打开网页 → 浏览器发出请求 → 等了一会儿 → 终于服务器开始回话了! 这段等待时间就是 TTFB。

理想的 TTFB 时间

理想的 TTFB 应该 < 800 毫秒 理想的 TTFB 应该 < 800 毫秒

  • TTFB 0 ~ 800ms: 良好。
  • TTFB 800ms ~ 1800ms: 需要改进
  • TTFB > 1800ms: 较差

TTFB 不是核心网页指标,因此网站不一定必须达到“良好”TTFB 阈值,前提是 TTFB 不会妨碍网站在重要指标方面获得理想得分。

如何优化 FCP

以下是一些导致 TTFB 差的常见原因:

  1. 服务器响应慢(处理逻辑复杂或阻塞)。

  2. 服务器地理位置过远。

  3. 数据库查询耗时过高。

  4. HTTP 重定向过多。

优化思路:

  1. 使用 CDN 缓存内容,靠近用户。

  2. 静态内容采用预渲染(SSG)或缓存。

  3. 数据库查询优化,避免阻塞。

  4. 减少重定向次数。

  5. 提前加载(如 preconnect, dns-prefetch)。

总结

指标 说明 理想值 影响
LCP 最大内容绘制时间 < 2.5 秒 用户首次看到主要内容的时长
INP 交互到下一次绘制时间 < 200ms 交互响应的流畅性
CLS 累计布局偏移 < 0.1 页面布局稳定性,避免跳动
FCP 首个内容绘制时间 < 1.8 秒 页面开始渲染的速度
TTFB 首个字节时间 < 200ms 服务器响应速度

参考