什么是 FCP?
首次内容绘制 (FCP) 衡量的是从用户首次导航到页面到页面的任何部分内容呈现在屏幕上的时间。对于此指标,“内容”指的是文本、图像(包括背景图像)、<svg>
元素或非白色 <canvas>
元素。

在前面图像中描绘的加载时间轴中,FCP发生在第二帧,因为那时第一个文本和图像元素被渲染到屏幕上。
您会注意到,虽然某些内容已呈现,但并非所有内容都已呈现。这是区分首次内容绘制和 最大内容绘制 (LCP) 的重要区别,后者旨在衡量页面主要内容何时完成加载。
良好的 FCP 分数是多少?
为了提供良好的用户体验,网站应力争将首次内容绘制时间控制在 1.8 秒 或更短。为了确保您为大多数用户达到此目标,一个好的衡量阈值是跨移动设备和桌面设备细分的页面加载的 第 75 个百分位数。
如何衡量 FCP
现场工具
实验室工具
在 JavaScript 中衡量 FCP
要在 JavaScript 中衡量 FCP,您可以使用 Paint Timing API。以下示例展示了如何创建一个 PerformanceObserver
,用于侦听名称为 first-contentful-paint
的 paint
条目,并将其记录到控制台。
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
console.log('FCP candidate:', entry.startTime, entry);
}
}).observe({type: 'paint', buffered: true});
在前面的代码片段中,记录的 first-contentful-paint
条目将告诉您第一个内容元素何时绘制完成。但是,在某些情况下,此条目对于衡量 FCP 无效。
以下部分列出了 API 报告的内容与指标计算方式之间的差异。
指标和 API 之间的差异
- API 将为在后台标签页中加载的页面分派
first-contentful-paint
条目,但在计算 FCP 时应忽略这些页面(仅当页面在整个过程中都处于前台时,才应考虑首次绘制时间)。 - 当页面从返回/前进缓存恢复时,API 不会报告
first-contentful-paint
条目,但 FCP 应在这些情况下进行衡量,因为用户将其体验为不同的页面访问。 - API 可能不会报告来自跨域 iframe 的绘制时间,但为了正确衡量 FCP,您应该考虑所有帧。子帧可以使用 API 将其绘制时间报告给父帧以进行聚合。
- API 从导航开始衡量 FCP,但对于 预渲染页面,FCP 应从
activationStart
衡量,因为这对应于用户体验到的 FCP 时间。
开发人员可以使用 web-vitals
JavaScript 库 来衡量 FCP,而不是记住所有这些细微的差异,该库会为您处理这些差异(在可能的情况下——请注意,iframe 问题未涵盖)。
import {onFCP} from 'web-vitals';
// Measure and log FCP as soon as it's available.
onFCP(console.log);
您可以参考 onFCP()
的源代码,以获取如何在 JavaScript 中衡量 FCP 的完整示例。
如何改进 FCP
要了解如何改进特定站点的 FCP,您可以运行 Lighthouse 性能审核,并注意审核建议的任何特定机会或诊断。
要了解如何(针对任何站点)全面改进 FCP,请参阅以下性能指南
- 消除渲染阻塞资源
- 缩小 CSS
- 移除未使用的 CSS
- 移除未使用的 JavaScript
- 预连接到必需的来源
- 减少服务器响应时间 (TTFB)
- 避免多次页面重定向
- 预加载关键请求
- 避免过大的网络负载
- 使用高效的缓存策略提供静态资源
- 避免过大的 DOM 大小
- 最小化关键请求深度
- 确保文本在 Webfont 加载期间保持可见
- 保持较低的请求计数和较小的传输大小
变更日志
有时,在用于衡量指标的 API 中会发现错误,有时在指标本身的定义中也会发现错误。因此,有时必须进行更改,这些更改可能会在您的内部报告和仪表板中显示为改进或退步。
为了帮助您管理这一点,对这些指标的实施或定义的所有更改都将在此变更日志中公开。
如果您对这些指标有反馈意见,可以在 web-vitals-feedback Google 网上论坛中提供。