Skip to main content
Performance

First Contentful Paint (FCP)

Published:

First Contentful Paint (FCP) measures the time from when the user first navigated to the page to when any part of the page's content is rendered on screen. Content means text, images (including background images), <svg> elements or non-white <canvas> elements.

FCP can be measured both in the lab and in the field. It is not a Core Web Vital: web.dev treats it as a supporting metric that helps diagnose loading problems that affect LCP.

What FCP measures

The clock starts at navigation, not when the server responds. In field data FCP therefore includes unload time from the previous page, connection setup, redirects and Time to First Byte (TTFB). A slow server or a redirect chain raises FCP before the browser has received a single byte of HTML.

Lighthouse does not count content inside iframes towards FCP. The Paint Timing API may also not report paints from cross-origin iframes, so JavaScript measurement can be incomplete there.

FCP thresholds

The web.dev threshold applies to field data: the 75th percentile of visits, segmented by mobile and desktop. The Lighthouse thresholds apply to a single lab test on a given device profile.

In Lighthouse 10, FCP carries 10% of the Performance score, the same as Speed Index. TBT (30%) and LCP and CLS (25% each) weigh more.

SourceGoodNeeds improvementPoor
web.dev (75th percentile of visits)≤ 1.8 s1.8–3.0 sover 3.0 s
Lighthouse, mobile0–1.8 s1.8–3 sover 3 s
Lighthouse, desktop0–0.9 s0.9–1.6 sover 1.6 s

FCP vs LCP vs TTFB

If a page shows a splash screen or a loading indicator, FCP can be fast while the user still sees nothing useful. That is why FCP diagnoses the start of loading, while perceived load speed is judged by LCP.

  • TTFB measures when the first byte of the response arrives. It precedes FCP and LCP, which is why web.dev recommends a server response fast enough for the 75th percentile of users to get a good FCP.
  • FCP measures when any content appears. That can be a logo, a heading or a loading indicator.
  • LCP measures when the largest content element in the viewport appears. It answers whether the main content is there yet.

How to improve FCP

  • Eliminate render-blocking resources. Stylesheets and synchronous scripts in <head> hold back the first paint until they have downloaded.
  • Reduce TTFB and avoid multiple redirects. Every extra network hop pushes FCP back.
  • Remove unused CSS and JavaScript, and minify what remains.
  • Preconnect to required origins and preload key requests.
  • Keep text visible while web fonts load. font-display: swap shows a system font straight away, which improves FCP and LCP, but the font swap can cause a layout shift (CLS).
  • Keep request counts and transfer sizes low, shorten critical request chains and avoid an excessive DOM size.
Visible text during font load, early connection
HTML
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<style>
  @font-face {
    font-family: "Brand";
    src: url("/fonts/brand.woff2") format("woff2");
    font-display: swap;
  }
</style>

How to measure FCP

In the lab, FCP is reported by Lighthouse, the Chrome DevTools Performance panel and PageSpeed Insights. Field data comes from the Chrome UX Report (CrUX), which PageSpeed Insights also shows, or from your own RUM.

The simplest way to measure FCP with real users is the web-vitals library. It cannot, however, measure paints inside cross-origin iframes.

Measuring FCP in the browser
JavaScript
import { onFCP } from 'web-vitals';

// Logs FCP as soon as it is available
onFCP(console.log);

Sources & further reading

See what delays your first screen

Insight combines lab results with field data when available and ranks performance issues by priority.