layout | title | authors | date | updated | description | tags | |||
---|---|---|---|---|---|---|---|---|---|
post |
First Contentful Paint (FCP) |
|
2019-11-07 |
2020-03-03 |
This post introduces the First Contentful Paint (FCP) metric and explains
how to measure it
|
|
{% Aside %} First Contentful Paint (FCP) is an important, user-centric metric for measuring perceived load speed because it marks the first point in the page load timeline where the user can see anything on the screen—a fast FCP helps reassure the user that something is happening. {% endAside %}
The First Contentful Paint (FCP) metric measures the time from when the page
starts loading to when any part of the page's content is rendered on the screen.
For this metric, "content" refers to text, images (including background images),
<svg>
elements, or non-white <canvas>
elements.
In the above load timeline, FCP happens in the second frame, as that's when the first text and image elements are rendered to the screen.
You'll notice that though some of the content has rendered, not all of it has rendered. This is an important distinction to make between First Contentful Paint (FCP) and Largest Contentful Paint (LCP) —which aims to measure when the page's main contents have finished loading.
FCP can be measured in the lab or in the field, and it's available in the following tools:
You can measure FCP in JavaScript using the Paint Timing
API. The following example shows how to
create a
PerformanceObserver
that listens for paint timing entries and logs the start time of the
first-contentful-paint
entry to the console:
// Catch errors since some browsers throw when using the new `type` option.
// https://bugs.webkit.org/show_bug.cgi?id=209216
try {
// Create the Performance Observer instance.
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntriesByName('first-contentful-paint')) {
// Log the value of FCP to the console.
console.log('FCP:', entry.startTime);
observer.disconnect();
}
});
// Start observing paint entry types.
observer.observe({
type: 'paint',
buffered: true,
});
} catch (e) {
// Do nothing if the browser doesn't support this API.
}
Note, in your own code, you'd likely replace the console.log()
with code that
sends the FCP value to your analytics service.
To provide a good user experience, sites should strive to have First Contentful Paint occur within 1 second of the page starting to load. To ensure you're hitting this target for most of your users, a good threshold to measure is the 75th percentile of page loads, segmented across mobile and desktop devices.
To learn how to improve FCP for a specific site, you can run a Lighthouse performance audit and pay attention to any specific opportunities or diagnostics the audit suggests.
To learn how to improve FCP in general (for any site), refer to the following performance guides:
- Eliminate render-blocking resources
- Minify CSS
- Remove unused CSS
- Preconnect to required origins
- Reduce server response times (TTFB)
- Avoid multiple page redirects
- Preload key requests
- Avoid enormous network payloads
- Serve static assets with an efficient cache policy
- Avoid an excessive DOM size
- Minimize critical request depth
- Ensure text remains visible during webfont load
- Keep request counts low and transfer sizes small