SEO

First Contentful Paint (FCP)

First Contentful Paint (FCP) measures how long it takes for the first piece of content — text, image, SVG, or non-white canvas — to render on screen after the user requests a page. It's the moment users see the first sign that "this page is responding."

First Contentful Paint (FCP) measures how long it takes for the first piece of content — text, image, SVG, or non-white canvas — to render on screen after the user requests a page. It's the moment users see the first sign that "this page is responding."

Why It Matters

Users staring at a blank screen bounce fast. Nielsen Norman Group research shows attention drops sharply once the first visual response crosses 1 second. FCP isn't an official Core Web Vital today, but it's a key component of the Lighthouse performance score and a leading indicator for LCP. If FCP is slow, LCP can never be good.

Thresholds

RatingFCP
Good≤ 1.8s
Needs Improvement1.8–3.0s
Poor> 3.0s

Measured at the 75th percentile (p75) of real-user data from the Chrome User Experience Report.

TTFB → FCP → LCP → INP

Page loading is a timeline of sequential metrics.

  1. TTFB: Time until the server sends the first byte
  2. FCP: Time until the first content is painted
  3. LCP: Time until the largest content element is painted
  4. INP: Time until a user interaction visually responds

The ordering matters: if TTFB is slow, FCP can't be fast, and LCP can't be fast either. Performance work must start "from the top."

What Slows FCP Down

Slow TTFB: A slow server slows FCP by the same amount.

Render-blocking resources: External CSS and synchronous JS in <head> must download and execute before the browser can paint. Too many or too large, and FCP stalls.

Large DOM size: Thousands of elements in the initial HTML cost parse and layout time.

Web font loading: Custom fonts not yet loaded cause FOIT (flash of invisible text), making FCP feel delayed.

Client-side rendering (CSR): React and Vue apps that paint content only after downloading and executing the JS bundle push FCP back significantly.

How to Optimize

Improve TTFB: CDN, server-side caching, and DB optimization — the foundation.

Eliminate render-blocking resources: Use async and defer to defer JS. Inline critical CSS and load the rest asynchronously.

Server-side rendering (SSR): Use frameworks like Next.js, Astro, or Remix to pre-generate HTML on the server.

Font optimization: font-display: swap shows fallback text immediately while custom fonts load. Use preload for critical fonts only.

Shrink JS bundles: Tree shaking, code splitting, and removing unused libraries all lower the initial bundle.

Image optimization: <link rel="preload"> the hero image and serve WebP or AVIF.

Measurement Tools

  • PageSpeed Insights: CrUX field data + lab data
  • Lighthouse: Page-level diagnostics
  • Chrome DevTools → Performance: FCP on the timeline
  • web-vitals JS library: Collect real-user data on your own site

Sources: