First Contentful Paint (FCP)
What First Contentful Paint measures, what's a good FCP score, why it isn't a Core Web Vital, how it differs from First Paint and LCP, and how to fix a slow one.
First Contentful Paint (FCP) is the time from when a page starts loading to when any part of its content — text, image, SVG, or non-white canvas — first renders. Good is ≤1.8 s at the 75th percentile of real users. It is NOT a Core Web Vital: the ranking signals are LCP, INP, and CLS. FCP is a diagnostic metric (lab and field) that's a building block of LCP — it happens at or before LCP — so it's mainly useful for catching render-blocking resources and slow TTFB. In Lighthouse 10 it's 10% of the Performance score. Fix it by eliminating render-blocking CSS/JS, cutting TTFB, inlining critical CSS, using font-display: swap, and preconnecting to required origins.
TL;DR — First Contentful Paint (FCP) is the moment a visitor sees the first bit of your page — any text, image, or graphic — instead of a blank white screen. Faster is better; under 1.8 seconds is the “good” mark. It’s a useful speed check, but it is not one of the metrics Google uses for ranking.
What FCP actually is
When someone clicks a link to your page, there’s a short stretch where they’re staring at nothing — a blank screen — while the browser fetches and processes your page. First Contentful Paint is the instant that blank screen turns into something real: a headline, a logo, a photo, anything the visitor can actually see.
That’s the whole idea. FCP answers one simple question: “How long until the user sees the page is alive and doing something?” A page that paints content in half a second feels fast. A page that sits blank for three seconds feels broken — and people leave.
Evidence for this claim FCP measures from navigation until the first text, image, SVG, or non-white canvas content is rendered. Scope: Current web.dev FCP definition and qualifying content types. Confidence: high · Verified: web.dev: First Contentful PaintWhat counts as “content”
FCP fires when the browser draws any of these onto the screen:
- Text (a heading, a paragraph, a nav link)
- Images, including background images
<svg>graphics- A non-white
<canvas>element
A plain background color by itself does not count — that’s a different, earlier thing called First Paint. FCP only counts when real content shows up.
What’s a good score?
Google’s bands, measured across real visitors:
| FCP time | Rating |
|---|---|
| 1.8 seconds or less | Good |
| 1.8 – 3.0 seconds | Needs improvement |
| Over 3.0 seconds | Poor |
You’ll see your FCP in tools like PageSpeed Insights and Lighthouse — the same reports that show your Core Web Vitals.
Does FCP affect my Google rankings?
No — not directly. This is the part most people get wrong. The metrics Google actually uses for ranking are the three Core Web Vitals: LCP, INP, and CLS. FCP isn’t one of them.
But here’s why it’s still worth watching: the things that make FCP slow — a sluggish server, big stylesheets and scripts that block the page from drawing — are often the same things that hurt Largest Contentful Paint (LCP), which is a ranking signal. So fixing FCP’s root causes frequently helps LCP too — but it’s not a guarantee, since LCP has causes of its own (the size and load priority of its specific largest element). Think of FCP as the smoke alarm: worth checking, but not proof the fire’s out.
The quick fixes
If your FCP is slow, the usual suspects (and what to do):
- Render-blocking files. CSS and JavaScript in your page’s
<head>can stop the browser from drawing anything until they finish loading. This is the #1 cause. - A slow server. If your server takes a long time to respond (high Time to First Byte), the browser can’t paint until the bytes arrive.
- Fonts that hide your text. Some font setups leave text invisible for up to three
seconds while a web font loads. Switching the rule to
font-display: swapshows fallback text immediately.
Want the technical version — the lab-vs-field gap, the FCP/LCP diagnostic chain, and the full fix list? Switch to the Advanced tab.
TL;DR — FCP is the time from navigation start to when any page content (text, image,
<svg>, or non-white<canvas>) first renders. It is not a Core Web Vital — it’s a supplementary, lab-and-field diagnostic metric, and a building block of LCP (FCP happens at or before LCP). Field thresholds (p75): Good ≤ 1.8 s, needs-improvement ≤ 3.0 s, poor > 3.0 s. In Lighthouse 10 it’s 10% of the Performance score. Because FCP’s clock starts at navigation — it includes redirect time, connection setup, and TTFB — lab (Lighthouse) and field (CrUX) numbers often diverge. Fix it where it lives: render-blocking CSS/JS first, then TTFB, then fonts.
What FCP measures (precisely)
Google’s definition, from Philip Walton’s web.dev article, is the accuracy spine here:
“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 the screen.” “Content,”
per the same doc, means “text, images (including background images), <svg> elements,
or non-white <canvas> elements.”
The word that does all the work is any. FCP doesn’t care what renders — a 40-pixel logo counts the same as a full hero image. It’s the “is anything on screen yet?” signal, which is exactly why it’s an early indicator rather than a completion metric.
Evidence for this claim FCP measures from navigation until the first text, image, SVG, or non-white canvas content is rendered. Scope: Current web.dev FCP definition and qualifying content types. Confidence: high · Verified: web.dev: First Contentful PaintOne detail that’s easy to miss and changes how you read the number: FCP’s clock starts at navigation, so it bundles in everything that happens before your HTML is even parsed. Google’s own Key Point: “FCP includes any unload time from the previous page, connection set up time, redirect time, and Time To First Byte (TTFB) which can be significant when measured in the field.” A server that takes 1.5 s to respond has already burned most of your 1.8 s budget before the browser has processed a single byte.
FCP is NOT a Core Web Vital
Let me be blunt about this because most pages hedge it: FCP is not a Core Web Vital and is not part of Google’s ranking signals. The Core Web Vitals are LCP, INP, and CLS — and FCP isn’t mentioned anywhere on Google’s Search ranking Core Web Vitals page.
What FCP is, in Google’s taxonomy, is an “Other Web Vital” — a supplementary metric that’s useful for diagnosis. web.dev puts it this way: “the metrics Time to First Byte (TTFB) and First Contentful Paint (FCP) are both vital aspects of the loading experience, and are both useful in diagnosing issues with LCP (slow server response times or render-blocking resources, respectively).”
So the honest framing for stakeholders is two-sided, and you should state both halves without flinching:
- FCP does not affect rankings directly. Don’t optimize FCP “for SEO.”
- FCP is a great diagnostic for LCP, which does affect rankings. Render-blocking resources show up in FCP first.
FCP vs First Paint (FP)
These get conflated constantly:
- First Paint (FP) fires when the browser paints anything at all — including a bare background color with no actual content.
- FCP fires only when eligible content renders: text, images (including
background images),
<svg>elements, or non-white<canvas>elements. That’s a specific, spec-defined list — not a loose “any DOM content” rule — and it’s worth keeping precise, since a background image counts even though it isn’t text in the DOM.
So FP ≤ FCP, always. On most pages they’re nearly identical, because painting a
background color with no content on top is rare. When there is a meaningful gap, it
usually means a cosmetic background painted before any real content did. The Paint
Timing API returns both first-paint and first-contentful-paint entries — but FCP is
the one worth analyzing; FP rarely tells you anything actionable.
FCP vs LCP
The other pair people merge:
- FCP = when any content paints. Fires early. Could be a tiny logo or a nav link.
- LCP = when the largest element in the viewport renders. Fires at or after FCP.
Google’s wording: FCP measures when any content is painted and LCP when the main content is painted, so LCP is intended to be more selective. Read that as “more selective,” not “certified correct” — neither metric proves the page’s actual main content is complete or useful to the visitor. FCP just confirms something eligible painted; LCP confirms the largest eligible candidate did. A page can have a fast FCP (logo at 0.5 s) and a slow LCP (hero image at 4 s) — that gap is itself a useful diagnostic. And if your FCP is close to your LCP, that’s often a good sign: it means the first thing painted is also the largest one, with no wasted early-paint on chrome that doesn’t matter to the user.
Evidence for this claim FCP answers when any eligible content first appears, while LCP tracks the largest eligible viewport candidate; neither metric proves the page's main content is complete or useful. Scope: field and lab Confidence: high · Verified: First Contentful Paint (FCP)One measurement oddity worth knowing: because of security restrictions on cross-origin image timing, the browser API can in rare cases report LCP earlier than FCP. That’s a measurement artifact, not something that physically happened.
Thresholds — and why lab and field disagree
Field thresholds (CrUX, p75): Good ≤ 1.8 s · needs improvement ≤ 3.0 s · poor > 3.0 s. Google’s guidance is to measure at the 75th percentile of page loads, split across mobile and desktop.
Evidence for this claim A good FCP is 1.8 seconds or less at the 75th percentile; above 3 seconds is poor. Scope: Current web.dev FCP field thresholds. Confidence: high · Verified: web.dev: First Contentful PaintBut Lighthouse desktop uses different, stricter cutoffs — green is roughly 0–0.9 s, orange 0.9–1.6 s, red over 1.6 s — because the lab runs a clean, throttled Chrome on a simulated device, not real-world conditions. (Those bands, like the score weights below, are Lighthouse-version-specific — this reflects the current audit doc as of this writing.) The Lighthouse FCP score is “a comparison of your page’s FCP time and FCP times for real websites, based on data from the HTTP Archive.”
This is the single most common source of FCP confusion, so internalize it:
The 1.8 s “good” line is the field (CrUX p75) threshold. Lighthouse desktop’s “green” line is ~0.9 s. They are different scales for different jobs.
Field and lab numbers diverge mainly because they sample different populations, not because one is universally “more true.” Lighthouse runs a single clean session on fixed device/network conditions. Field/CrUX aggregates real devices, real networks, cache states, and navigation types — including back/forward-cache restores and prerendered pages, which don’t automatically get a fresh FCP the way a normal navigation does; they need their own lifecycle handling (the web-vitals library does this for you). On most sites the field number does read higher — real users carry redirect chains, previous- page unload time, and cold connections a lab run skips — but that’s a tendency, not a rule. Before reading a lab/field gap as a problem, check you’re comparing like-for-like (same device class, same network conditions). Use field data for your real-world number and Lighthouse for diagnosis.
Where FCP sits in the Lighthouse score
In Lighthouse 10 — the current version as of this writing, not a permanent figure — FCP is 10% of the Performance score. The full weighting:
| Metric | Weight |
|---|---|
| Total Blocking Time (TBT) | 30% |
| Largest Contentful Paint (LCP) | 25% |
| Cumulative Layout Shift (CLS) | 25% |
| First Contentful Paint (FCP) | 10% |
| Speed Index | 10% |
The Performance score is a weighted average of the individual metric scores, and Google notes the weightings change over time as their research evolves — FCP has held at 10% from Lighthouse 8 through 10, but confirm against whatever version you’re running before treating “10%” as timeless. The practical read: a perfect FCP can only move your Lighthouse number so far — and a bad FCP often points at a bad LCP too (they share root causes), though that’s an overlap worth checking, not something the score guarantees.
What causes a slow FCP
In rough priority order:
- Render-blocking resources — the #1 killer. CSS and synchronous JS in
<head>force the browser to wait: it can’t build the CSSOM and render tree, so it can’t paint anything, until those files are downloaded and parsed. - High TTFB — FCP can’t fire before bytes arrive. A slow server is the first domino, and it’s inside the FCP measurement.
- Redirect chains — every redirect is a full round-trip added before the first byte.
- Webfont loading strategy —
font-display: block(or no rule) can leave text invisible for up to ~3 seconds. Even if paint technically fires on a background, the user sees nothing useful.
How to fix it
The full list, but with a priority order the docs don’t give you. These are the common levers, not universal ones — check your own trace or filmstrip first to see which resource or phase is actually delaying your FCP candidate before reaching for fixes (preconnect, preload, a font-display change) that may not apply to your page:
Do these first (biggest wins):
- Eliminate render-blocking CSS and JavaScript. Inline the critical, above-the-fold
CSS directly in
<head>; load the rest asynchronously; addasync/deferto non-critical scripts. Repositioning a<link>tag does not help — the browser won’t paint until all CSS is loaded and parsed regardless of where the tag sits. - Reduce TTFB (server response time). Caching, a CDN, a faster origin — anything that gets the first byte out sooner directly shaves FCP.
- Fix font loading. Use
font-display: swap(shows fallback text immediately, swaps in the web font when ready) orfont-display: optional(skips the web font if it isn’t already cached). Avoidfont-display: blockfor critical text — it’s the worst for FCP.
Then tidy up the rest:
- Preconnect to required origins with
<link rel="preconnect">— establishing early connections to important third-party origins can save 100–500 ms. - Preload key requests (
<link rel="preload">) for a critical font or the LCP image. - Minify CSS, remove unused CSS, remove unused JavaScript — smaller files parse and unblock paint faster.
- Avoid multiple redirects, avoid enormous network payloads, serve static assets with an efficient cache policy, avoid an excessive DOM size, and minimize critical request depth. General payload hygiene that all feeds first paint.
The FCP → TTFB → LCP diagnostic chain
This is how I’d actually use FCP, and it’s the framing the docs gesture at but don’t develop. Treat the three loading metrics as one workflow:
- FCP is high → check for render-blocking resources (CSS/JS in
<head>). That’s the most common cause and the fastest win. - Also check TTFB — because FCP includes it, a slow server inflates FCP before any render-blocking even enters the picture. web.dev’s guidance: because TTFB precedes both FCP and LCP, your server should respond fast enough that the 75th percentile of users hit a “good” FCP.
- These same problems often cascade into LCP — the metric that’s actually a ranking signal — because FCP and LCP frequently share root causes. That’s an overlap worth checking, not a guarantee: LCP has factors of its own (the size, priority, and load path of its specific largest element), so fixing FCP’s causes doesn’t promise a fixed LCP. It’s the right first place to look, not the last step.
That’s the value of FCP for an SEO: it’s a cheap, early read on whether the loading path is healthy, before the more selective LCP measurement even completes.
AI summary
A condensed take on the Advanced version:
- FCP = time from navigation start to when any content first renders — text,
images (incl. background),
<svg>, or non-white<canvas>. It’s the “is anything on screen yet?” signal. - FCP is NOT a Core Web Vital. The ranking signals are LCP, INP, CLS. FCP is a supplementary, lab-and-field diagnostic metric — not a direct ranking factor.
- It’s a building block of LCP (FCP happens at or before LCP), so it often catches the same render-blocking resources and slow TTFB that hurt LCP — which does affect rankings — but fixing FCP’s causes doesn’t guarantee LCP is fixed; LCP has factors of its own.
- Field thresholds (CrUX p75): Good ≤ 1.8 s · needs improvement ≤ 3.0 s · poor > 3.0 s.
- Lab ≠ field, and “field is always higher” is a tendency, not a rule. Lighthouse desktop’s ~0.9 s “green” line is stricter than the 1.8 s field threshold because it’s one clean run on fixed conditions; field/CrUX aggregates real devices, networks, cache states, and navigation types (including bfcache restores and prerendered pages). Match populations before reading a gap as a problem — use field for your real-world number, lab for diagnosis.
- FCP vs FP: First Paint fires on any paint (even a background color); FCP needs eligible content (text, images incl. background images, SVG, non-white canvas). FP ≤ FCP always.
- FCP vs LCP: FCP = any eligible content; LCP = largest eligible candidate. Neither proves the page’s real main content is complete or useful — they’re proxies. Fast FCP + slow LCP is a real, common gap.
- Lighthouse 10 (current as of this writing) weight: 10% — TBT 30%, LCP 25%, CLS 25%, FCP 10%, Speed Index 10%; weights shift between Lighthouse versions.
- Top fixes, in order: eliminate render-blocking CSS/JS → reduce TTFB → fix fonts
(
font-display: swap/optional) → preconnect/preload → minify/cache/DOM hygiene.
Official documentation
Primary-source documentation on FCP from Google.
web.dev (Google)
- First Contentful Paint (FCP) — Philip Walton’s canonical definition, the “what counts as content” list, the 1.8 s threshold, the Key Point about TTFB/redirects, and how to measure FCP with the Paint Timing API and the web-vitals library.
- Web Vitals — where FCP sits: an “Other Web Vital,” supplementary to the Core Web Vitals (LCP, INP, CLS), useful for diagnosing LCP.
- Largest Contentful Paint (LCP) — the FCP-vs-LCP distinction and how the two relate.
- Time to First Byte (TTFB) — why TTFB precedes (and is included in) FCP.
- User-centric performance metrics — FCP’s classification as both a lab and a field metric.
Lighthouse / Chrome Developers
- First Contentful Paint audit — the Lighthouse desktop rating bands (green ≤ 0.9 s) and how the FCP score is computed against HTTP Archive data.
- Lighthouse performance scoring — the metric weights, including FCP at 10% of the Performance score in Lighthouse 10.
Google Search Central
- Core Web Vitals & Google Search — the ranking page; lists LCP, INP, and CLS. FCP is not on it, which is the point.
Quotes from the source
On-the-record statements from Google’s documentation. Each link is a deep link that jumps to the quoted passage on the source page.
web.dev — the definition
- “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 the screen.” — Philip Walton, First Contentful Paint (FCP), web.dev (updated Dec 6 2023). Jump to quote
web.dev — the threshold
- “sites should strive to have a First Contentful Paint of 1.8 seconds or less.” — same source. Jump to quote
web.dev — what FCP includes (the Key Point)
- “FCP includes any unload time from the previous page, connection set up time, redirect time, and Time To First Byte (TTFB) which can be significant when measured in the field.” — same source.
web.dev — FCP’s role relative to the Core Web Vitals
- “the metrics Time to First Byte (TTFB) and First Contentful Paint (FCP) are both vital aspects of the loading experience, and are both useful in diagnosing issues with LCP (slow server response times or render-blocking resources, respectively).” — Web Vitals, web.dev. Jump to quote
Lighthouse — how the FCP score is computed
- “Your FCP score is a comparison of your page’s FCP time and FCP times for real websites, based on data from the HTTP Archive.” — First Contentful Paint audit, developer.chrome.com.
Lighthouse — how the Performance score works
- “The Performance score is a weighted average of the metric scores.”
- “The weightings have changed over time because the Lighthouse team is regularly doing research and gathering feedback to understand what has the biggest impact on user-perceived performance.” — Lighthouse performance scoring, developer.chrome.com.
#:~:text= deep link; confirm them against the live pages before treating any quote as final. Lighthouse weights are quoted for Lighthouse 10 — re-verify if a newer Lighthouse version has shipped. Slow-FCP triage checklist
When FCP is high, work down this list in order — it’s roughly biggest-win-first:
- Check the field number, not just Lighthouse. Read CrUX/PageSpeed Insights p75 for the real FCP; use Lighthouse only to diagnose.
- Hunt render-blocking resources. CSS and synchronous JS in
<head>are the #1 cause — Lighthouse’s “Eliminate render-blocking resources” audit lists them. - Inline critical above-the-fold CSS; load the rest asynchronously.
- Add
async/deferto non-critical scripts; move third-party tags after first paint. - Measure TTFB. It’s inside FCP — a slow server inflates FCP before anything else. Add caching / a CDN / a faster origin.
- Kill redirect chains — each hop is a full round-trip before the first byte.
- Fix fonts: use
font-display: swaporoptional; neverblockfor critical text. Preload the critical font file. - Preconnect to required third-party origins; preload the LCP image / key requests.
- Trim payload: minify CSS, remove unused CSS/JS, efficient cache policy, smaller DOM, shorter critical request depth.
- Re-check LCP afterward — the same fixes should have moved it, and LCP is the one that affects rankings.
FCP cheat sheet
Field thresholds (CrUX, 75th percentile)
| FCP time | Rating |
|---|---|
| ≤ 1.8 s | Good |
| 1.8 – 3.0 s | Needs improvement |
| > 3.0 s | Poor |
Lighthouse desktop rating (lab — note: stricter than field)
| FCP time | Color |
|---|---|
| 0 – 0.9 s | Green (fast) |
| 0.9 – 1.6 s | Orange (moderate) |
| Over 1.6 s | Red (slow) |
Lighthouse 10 Performance-score weights (current as of this writing — weights shift between Lighthouse versions)
| Metric | Weight |
|---|---|
| Total Blocking Time | 30% |
| Largest Contentful Paint | 25% |
| Cumulative Layout Shift | 25% |
| First Contentful Paint | 10% |
| Speed Index | 10% |
The three loading metrics, untangled
| Metric | Fires when… | Core Web Vital? |
|---|---|---|
| First Paint (FP) | the browser paints anything, even a background color | No |
| First Contentful Paint (FCP) | any real content paints (text/image/SVG/canvas) | No (diagnostic) |
| Largest Contentful Paint (LCP) | the largest viewport element renders | Yes |
Order of events: FP ≤ FCP ≤ LCP.
What counts as “content” for FCP
text · images (incl. background images) · <svg> elements · non-white <canvas> elements
Fast facts
- FCP’s clock starts at navigation — it includes redirect time, connection setup, and TTFB.
- FCP is measurable in both lab and field.
font-display: useswap/optional; avoidblock(invisible text up to ~3 s).- Preconnect to third-party origins can save 100–500 ms.
Patrick's relevant free tools
- Page Speed Test & Core Web Vitals Checker — One sentence tells you whether a page passes Core Web Vitals and what to fix first — real Chrome user data (CrUX) with a Lighthouse lab fallback, mobile and desktop side by side, loudly-labeled data sources, and prioritized diagnostic fixes. Plus a bulk origin scorecard with CSV export.
- Core Web Vitals History & Competitor Comparison — Chart 40 weeks of real-Chrome-user Core Web Vitals — p75 LCP, INP, CLS, FCP, and TTFB from the Chrome UX Report — and compare up to 5 origins or URLs on one chart. Plus a competitor Leaderboard that ranks curated groups of SEO and page-speed tools on each metric. Pass/fail scorecards, mobile vs desktop, shareable links, CSV export.
- Hosting Checker — Find a domain's public IP network, CDN or edge platform, DNS and mail-host evidence, and response transfer facts without pretending a proxy reveals the origin.
Tools for measuring FCP
Field (real-user) data
- PageSpeed Insights — shows your URL’s CrUX p75 FCP (field) alongside a Lighthouse (lab) run.
- Chrome User Experience Report (CrUX) — the real-user dataset behind the field numbers, via the API or BigQuery.
- web-vitals JavaScript library — drop
onFCP(console.log)(or send it to your analytics) to capture FCP from your own visitors; it handles bfcache and background-tab edge cases.
Lab (simulated) data
- Lighthouse — in Chrome DevTools, PageSpeed Insights, or the CLI. Use it to diagnose FCP (the “Eliminate render-blocking resources” audit is the key one).
- Chrome DevTools Performance panel — see exactly when first paint and first contentful paint fire on a recorded load.
Measure it yourself with the Paint Timing API
new PerformanceObserver((entryList) => {
for (const entry of entryList.getEntriesByName('first-contentful-paint')) {
console.log('FCP candidate:', entry.startTime, entry);
}
}).observe({type: 'paint', buffered: true});Or use the web-vitals library (recommended)
import {onFCP} from 'web-vitals';
onFCP(console.log);A few caveats the raw API doesn’t handle that the web-vitals library does: it ignores
FCP fired for background tabs, still reports FCP when a page is restored from the
back/forward cache (a fresh navigation event doesn’t automatically fire for a
bfcache restore, so it needs explicit handling), and uses activationStart rather than
navigation start as the clock origin for prerendered pages. Cross-origin iframe
paint timing remains a known gap — a page whose main content renders inside one can show
a misleadingly fast FCP.
FCP mistakes that hide the real bottleneck
- Treating FCP as a Core Web Vital. FCP is a useful diagnostic, but LCP, INP, and CLS are the Core Web Vitals used in Google’s ranking systems. Use FCP to investigate the blank-screen phase, not as a substitute for field CWV data.
- Optimizing a tiny logo because it becomes the first paint. An earlier but meaningless paint can improve FCP while the useful page content still arrives late. Check LCP and the filmstrip alongside FCP so the change improves what a visitor actually sees.
- Starting with image compression when the page is blank. If nothing can paint, the usual blockers are server response time, render-blocking CSS, synchronous JavaScript, or fonts. Follow the request waterfall before changing unrelated assets.
- Comparing unrelated Lighthouse runs. Device emulation, network conditions, cache state, and run-to-run variation all move a lab FCP. Compare repeated runs under the same settings and confirm the result with field data where available.
The blank-screen budget
Break FCP into three consecutive questions instead of treating the final number as one problem:
- How long before the HTML arrives? Inspect TTFB. A slow response means the browser cannot begin useful work, so start with the server, cache, redirects, or connection setup.
- How long before the browser can render? Inspect render-blocking stylesheets, synchronous scripts, and font behavior. The HTML may be present while the main thread or render path is still blocked.
- What actually becomes the first content? Use a filmstrip or trace to confirm that the first paint is meaningful text or imagery, not a token element that makes the metric look better without improving the experience.
The framework keeps fixes in order: delivery first, rendering second, usefulness third. Re-run the same lab profile after each change so you know which phase moved.
Test yourself: First Contentful Paint
Five quick questions on what FCP measures and how to diagnose it. Pick an answer for each, then check.
Resources worth your time
Google / web.dev
- First Contentful Paint (FCP) — the canonical reference: definition, thresholds, measurement code, and the full optimization list.
- Web Vitals — how FCP relates to the Core Web Vitals and why it’s a diagnostic metric.
- Largest Contentful Paint (LCP) — the metric FCP helps you diagnose, and a Core Web Vital.
- Time to First Byte (TTFB) — the server-response metric that lives inside FCP.
Lighthouse
- First Contentful Paint audit — desktop rating bands and how the score is computed.
- Lighthouse performance scoring — the metric weights, FCP at 10%.
My related writing
- The Beginner’s Guide to Technical SEO — where page speed fits in the bigger picture.
- Core Web Vitals: What They Are & How to Improve Them — the ranking-signal metrics FCP feeds into.
From around the industry
- First Contentful Paint (FCP) — Philip Walton’s canonical Google article: definition, thresholds, Paint Timing API code, and the full optimization list.
- Web Vitals — Google’s framework explaining where FCP sits (an “Other Web Vital,” supplementary to the Core Web Vitals) and its role in diagnosing LCP.
- First Contentful Paint audit — Chrome Developers doc covering Lighthouse desktop rating bands and how the FCP score is computed against HTTP Archive data.
- Time to First Byte (TTFB) — Google’s guide on why TTFB precedes and is included in FCP, and how a slow server eats your FCP budget before the browser paints a single pixel.
- Eliminate render-blocking resources — Chrome Developers guide on the #1 FCP killer: CSS and synchronous JS in <head> that block the browser from painting.
- Ensure text remains visible during webfont load — Chrome Developers audit explaining font-display values and why
blockdelays FCP whileswaporoptionalkeeps text visible. - First Contentful Paint — NitroPack’s practical FCP guide with CMS-specific optimization tips and a clear field-vs-lab explanation.
Stats worth citing
- Good FCP = ≤ 1.8 s at the 75th percentile of real users; needs-improvement up to 3.0 s; poor beyond that (field/CrUX thresholds). Source
- Lighthouse desktop is stricter: ~0–0.9 s is “green,” because the lab runs a throttled, simulated environment rather than real-world conditions. Source
- FCP is 10% of the Lighthouse 10 Performance score (current as of this writing — weights shift between Lighthouse versions) — alongside TBT 30%, LCP 25%, CLS 25%, and Speed Index 10%. Source
- Preconnecting to third-party origins can save 100–500 ms of load time by establishing early connections. Source
FCP
First Contentful Paint — the time from when a page starts loading to when any part of its content (text, image, SVG, or non-white canvas) first renders. Good is ≤1.8 s at the 75th percentile. It's a diagnostic metric, not a Core Web Vital.
Related: Core Web Vitals, TTFB, LCP
FCP
First Contentful Paint (FCP) measures the time from when the user first navigates to a page to when any part of that page’s content is first rendered on screen. “Content” here means text, images (including background images), <svg> elements, or non-white <canvas> elements — so FCP fires the moment the user sees anything real, even a logo or a single line of text.
FCP is not a Core Web Vital. It’s a supplementary, diagnostic metric that Google measures in both the lab (Lighthouse, PageSpeed Insights, DevTools) and the field (CrUX). Its main job is to help diagnose Largest Contentful Paint (LCP) problems caused by render-blocking resources — FCP always happens at or before LCP, so it’s the early-warning signal in the loading sequence. The three Core Web Vitals that actually feed Google’s ranking systems are LCP, INP, and CLS.
The field thresholds, measured at the 75th percentile of real users: Good ≤ 1.8 s, Needs improvement ≤ 3.0 s, Poor > 3.0 s. In Lighthouse 10 (current as of this writing — weights shift between versions), FCP is worth 10% of the Performance score. The biggest fixes are eliminating render-blocking CSS/JS, reducing Time to First Byte (TTFB), inlining critical CSS, using font-display: swap, and preconnecting to required origins — but check your own trace to confirm which of these is actually the bottleneck on your page.
Related: Core Web Vitals, TTFB, LCP
Build-time retrieval analysis plus live signals for this exact article. The automatic chunk report includes a deterministic readiness score and is ready without a model download.
Search Console
sampleGA4 traffic (28d)
sampleCloudflare traffic (7d)
sampledCrUX field data (28d, phone)
sampleGoogle NLP entities
localChangelog
Updated Jul 17, 2026.
Editorial summary and recorded change details.Summary
Version-gated Lighthouse-specific numbers, removed the 'field is always higher/more true' framing, and stopped implying fixing FCP guarantees an LCP fix.
Change details
-
Qualified Lighthouse 10 weight and desktop rating bands as version-specific, softened 'fixing FCP almost always fixes LCP' to an overlap (not a guarantee) since LCP has causes of its own, added bfcache/prerender lifecycle detail to the field-vs-lab section, and tightened the FCP-vs-FP and FCP-vs-LCP eligibility wording to match the spec's 'eligible content' definition instead of 'DOM content'/'main content.'
Full comparison unavailable — no prior snapshot was archived for this revision.