FCP

On this page 7

FCP, short for First Contentful Paint, is the web performance metric that measures the time from the start of navigation until the browser renders the first piece of DOM content, such as text, an image, a non-white canvas or an SVG element. It answers a simple user question: when does the page visibly start to load?

In web performance work, FCP sits between server-side timing and full-content metrics. It comes after TTFB, which reflects how quickly the first byte arrives, and usually before LCP, which marks the moment the largest visible element appears. A fast FCP reassures visitors that something is happening, while a slow FCP is often the first sign of render-blocking resources or a sluggish server.

How the browser determines FCP

The browser records FCP at the first frame that paints contentful DOM content. The timestamp is measured relative to the navigation start, so it includes redirects, DNS lookup, connection setup, server response, HTML parsing, style calculation, layout and the paint itself.

The rule for what counts is precise. Text nodes, images, background images, SVG and non-white canvas elements qualify. A white background, a plain colored body or an empty container does not qualify, which is why First Paint (FP) and FCP can differ: FP fires on any pixel change, while FCP waits for real content. Content inside iframes is not included in the parent page’s FCP.

The table below shows which rendered items trigger the metric and which do not.

Rendered itemCounts for FCPNote
Visible textYesIncludes text drawn with a fallback font
Image or background imageYesAny decoded image that paints pixels
SVG elementYesInline or referenced vector graphics
CanvasOnly if non-whiteA blank canvas does not qualify
Page background colorNoTriggers First Paint only
Iframe contentNoMeasured within the iframe’s own document
What counts as contentful paint

In code, the value is exposed through the Paint Timing API. A PerformanceObserver listening for entries of type paint receives an entry named first-contentful-paint, whose startTime is the FCP in milliseconds. Real-user monitoring scripts read this entry and report it together with other metrics.

FCP thresholds and how they are scored

FCP is judged against widely used thresholds measured at the 75th percentile of page loads, segmented by mobile and desktop. Using the 75th percentile means most visitors, not only those on fast connections, must have a good experience for a page to pass.

RatingFCP valueInterpretation
Good1.8 s or lessVisitors see content quickly
Needs improvementOver 1.8 s up to 3.0 sNoticeable blank period
PoorOver 3.0 sHigh risk of abandonment and frustration
Common FCP rating bands

Lab tools such as Lighthouse also include FCP in their composite performance score, where it carries a modest weight compared with LCP and total blocking time. The exact weighting changes between tool versions, so teams should treat the lab score as a diagnostic aid rather than a target in itself.

FCP is not one of the Core Web Vitals. It remains a supporting diagnostic metric: a slow FCP almost always produces a slow LCP, because the largest element cannot appear before the first content does.

FCP compared with neighboring loading metrics

FCP is best understood as one step in a chain of loading milestones. Each milestone isolates a different part of the loading process, and comparing them shows where time is lost.

MetricWhat it marksMain influences
TTFBFirst byte of the HTML responseServer work, caching, network latency
First PaintAny pixel change after navigationBackground styles, early rendering
FCPFirst text, image, SVG or canvas contentRender-blocking CSS and scripts, fonts
LCPLargest visible image or text blockHero image size, priority, rendering
Speed indexHow quickly the viewport fills visuallyProgressive rendering of all content
FCP and related loading metrics

The gap between TTFB and FCP is especially informative. A small gap means the browser can paint almost as soon as the HTML arrives. A large gap, often over one second on mobile, points to blocking stylesheets, synchronous scripts in the document head or web fonts that hide text while they download.

Techniques that improve FCP

Improving FCP means shortening the critical rendering path, the sequence of resources the browser must fetch and process before it can paint. Every resource that blocks rendering adds network round trips and processing time before the first frame.

TechniqueWhat it changesTypical effect
Reduce server response timeCaching, edge delivery, faster backendLowers TTFB and FCP together
Inline critical CSSAbove-the-fold styles in the HTMLRemoves a blocking stylesheet request
Defer non-critical scriptsdefer or async on script tagsParser no longer stops for JavaScript
Use font-display swapText shown in a fallback font firstText paints before the web font loads
Preload key resourcesrel=preload for critical fonts or CSSResources start downloading earlier
Reduce redirectsDirect links to the final URLRemoves whole round trips
Common FCP optimizations

Rendering strategy matters as well. Pages built with server-side rendering or static generation deliver ready HTML and usually paint sooner than pages that rely on client-side rendering, where an empty shell waits for a JavaScript bundle to download, parse and execute before any content appears.

Pitfalls when interpreting FCP

FCP is easy to measure but easy to misread. The most important limitation is that it says nothing about whether the first content is useful; a cookie banner, a loading spinner or a header logo can trigger FCP while the main content is still missing.

  • Spinners and skeletons can flatter FCP without improving the experience, because they count as content while real information is absent.
  • Lab and field values differ. A test on a fast machine may show 0.8 s while real visitors on mid-range phones experience 2.5 s or more.
  • Back-forward cache restores and prerendered pages can report very low or adjusted values, so they should be segmented in reports.
  • Background tabs distort timing, because browsers delay rendering for pages that are not visible; monitoring scripts should ignore such loads.
  • Averages hide the slow tail. The 75th percentile, not the mean, reflects what a substantial share of visitors experience.

For these reasons, FCP should be read together with LCP, CLS and INP rather than in isolation. A good FCP combined with a poor LCP usually means the page shows a frame quickly but delays the content that visitors came for.

Understanding it simply

FCP measures how long a visitor stares at a blank screen. The clock starts when someone clicks a link and stops the moment anything meaningful, such as a headline or a picture, appears on the page.

Think of entering a restaurant. Being greeted at the door does not mean the meal has arrived, but it tells you that someone has noticed you and the service has started. FCP is that greeting: a quick one keeps people patient, while a long silence makes them wonder whether to leave.

Applied in practice

An online retailer notices in its field data that mobile visitors experience an FCP of 3.4 seconds at the 75th percentile, which falls in the poor band. Investigation shows a TTFB of 0.6 s, so the server is not the main problem. The waterfall reveals two large stylesheets and a synchronous analytics script in the document head, plus a web font configured to hide text until it loads.

The team inlines about 12 KB of critical CSS, loads the remaining styles asynchronously, adds defer to the analytics script and switches the font to font-display: swap. After deployment, the 75th percentile FCP drops to 1.6 seconds, moving the page into the good band, and LCP improves as well because the hero image no longer waits behind blocking resources.