First Contentful Paint measures when the browser first renders text, an image, a non-white canvas, or an SVG from the page. It answers a narrow but useful question: how long did the visitor wait before seeing any page content?
FCP is not a current Core Web Vital, and it does not tell you when the main content is ready. It remains valuable for diagnosing blank-screen time and the early critical rendering path.
What FCP measures
FCP starts when navigation begins and ends at the first contentful paint. It can therefore include:
- unload time from the previous document;
- redirects;
- DNS, connection, and TLS setup;
- Time to First Byte;
- HTML download and parsing;
- render-blocking CSS and scripts;
- font or resource work needed before anything visible can paint.
A background color alone is not contentful. Text, images including CSS background images, SVG, and non-white canvas content can qualify.
FCP differs from LCP. A header or small icon can create an early FCP while the primary article, hero, or product image appears much later. Diagnose both when the page starts quickly but still feels incomplete.
What is a good FCP value
The current thresholds documented by web.dev's FCP reference are:
| FCP | Rating |
|---|---|
| 1.8 seconds or less | Good |
| Over 1.8 through 3 seconds | Needs improvement |
| Over 3 seconds | Poor |
Field classification uses the 75th percentile of page visits, segmented by mobile and desktop. FCP is reported in PageSpeed field data when sufficient Chrome UX Report samples exist, but it is not one of the three metrics used for the current Core Web Vitals pass assessment.
Treat 1.8 seconds as a shared assessment threshold, not a promise that every page at 1.79 seconds is excellent. Improve the experience based on user impact and the full metric set.
Measure FCP correctly
Use PageSpeed Insights to view field and lab context. Confirm whether the field data is for the exact URL or the whole origin. Use Chrome DevTools Performance to inspect the document request, blocking resources, parsing, styles, scripts, and the FCP marker.
For reliable comparisons:
- Test the deployed URL, not a development server.
- Keep mobile or desktop mode, location, authentication, and consent state consistent.
- Run several lab tests and compare a representative median.
- Record TTFB, FCP, LCP, transferred bytes, and critical request chains.
- Save a trace before and after the change.
Local PerformanceObserver instrumentation can expose paint entries for debugging, but production RUM should use a maintained implementation such as the web-vitals library to handle lifecycle details. Protect privacy and avoid attaching sensitive URL parameters or user data.
Published measurement histories on IndieTools Speed can show when FCP changes. They do not replace a trace that explains why it changed.
Break the delay into phases
An FCP fix depends on where the time is spent.
Before the first byte
Look for redirect chains, slow edge routing, cold starts, server work, database queries, cache misses, and upstream APIs. Browser-side minification cannot recover time spent waiting for the HTML document.
After the first byte, before paint
Look for blocking stylesheets, synchronous scripts, large HTML, deep critical request chains, slow critical fonts, expensive style calculation, or a client-rendered shell with no useful server HTML.
FCP is early but LCP is late
The page is no longer blank, but the main resource is delayed. Investigate LCP discovery, priority, transfer, and render delay rather than optimizing a small logo that already paints quickly.
This phase-based view prevents generic work that improves file size but not the measured bottleneck.
Reduce document and server delay
Remove avoidable redirects. Link directly to the canonical HTTPS host, update old internal links, and avoid routing every visit through a locale or authentication bounce when the destination can be resolved earlier.
At the server:
- profile database and API calls in the document request;
- cache public responses only with correct variation and invalidation;
- move nonessential media processing and aggregation out of the request path;
- avoid serial calls when independent work can run concurrently;
- monitor queue time, cold starts, and connection pools;
- serve visitors through an appropriate edge or CDN strategy.
Measure at the browser, edge, application, and database so one layer is not blamed for another. If TTFB is already small, focus on the render path.
Remove render-blocking work
The browser generally needs CSS before it can render styled content. Keep critical CSS small, remove unused rules carefully, and split page-specific styles where the architecture supports it. Minification reduces transfer but does not automatically eliminate blocking.
JavaScript without suitable scheduling can block the parser. For scripts that do not need to run during parsing:
<script defer src="/assets/site-navigation.js"></script>
defer preserves document order and runs after parsing. async runs when the file is ready and does not preserve order, so it is appropriate only for independent code. Modules are deferred by default, but their dependency graph can still be large.
Do not change script scheduling without testing. Consent, analytics, navigation, forms, commerce, and hydration may depend on execution order. Remove unused code before applying increasingly complex loaders.
Inspect the critical request chain. Preload can help a late-discovered resource that is certainly needed for initial paint, but preloading many resources creates competition. Use it sparingly and confirm that the resource is consumed promptly.
Keep text visible during font loading
An early heading can be FCP, so font strategy affects blank-screen time. Limit families, weights, styles, and character sets. Serve WOFF2 where appropriate, use long caching for versioned font URLs, and avoid loading the same family from multiple providers.
Use a font-display value that matches the product's rendering policy. swap can keep text visible with a fallback, while optional may avoid a late swap under some conditions. Both require testing for CLS, brand requirements, and readability.
@font-face {
font-family: "Product Sans";
src: url("/fonts/product-sans-regular.woff2") format("woff2");
font-style: normal;
font-weight: 400;
font-display: swap;
}
Preload only a font used by important initial text. A preload for every weight spends bandwidth before the browser knows which files the page needs.
Avoid client-rendered blank shells
A single-page application that serves only an empty root element must download and execute JavaScript before content can create FCP. Use server rendering, static generation, or meaningful initial HTML when the framework and product permit it.
Keep the primary heading, navigation, article, product summary, or loading state visible without waiting for a large client bundle. If personalized data needs time, render a stable and accessible shell with realistic reserved space, then enhance it.
Hydration should not replace useful server HTML with a different layout. A mismatch can delay paint, create CLS, and duplicate work. Profile route bundles, dynamically import optional heavy features, and avoid putting the entire page behind one client-only component for convenience.
Control third parties and connection cost
Every external origin may require DNS, connection, and TLS work. Third-party scripts can also block parsing or occupy the main thread before paint.
Inventory analytics, consent, ads, chat, reviews, video, social embeds, experiments, and tag-manager contents. Load only what the route needs, respect consent, and prefer interaction-based or viewport-based loading for nonessential features when the vendor supports it.
preconnect can help a critical external origin, but each connection consumes resources. Use it only when a necessary early request is known and measure the result. A first-party proxy does not erase the JavaScript execution cost of a third party.
Validate without gaming the metric
After a change:
- compare repeated equivalent lab runs;
- verify the first painted content is useful and accessible;
- confirm LCP, CLS, and interaction behavior did not regress;
- test cold and warm caches, mobile and desktop, and relevant consent states;
- check functionality, analytics integrity, and error handling;
- deploy with a rollback path;
- watch real-user FCP and Core Web Vitals through their reporting windows.
Do not display an artificial pixel, hide real content from the measurement tool, or delay essential features only to trigger an earlier FCP. That improves the marker without improving the experience.
For the wider field assessment, continue with What Are Core Web Vitals?. For unexpected movement after the first paint, use What Is CLS and How to Fix It.


