First Contentful Paint (FCP) marks the first time the browser paints any content from the DOM: text, an image, a non-white background, an SVG. It is the visitor’s first signal that something is happening, and it sits early on the timeline, so everything from TTFB through render-blocking resources decides when it fires.
Where the 1.8-second line sits
The Good / Needs-work / Poor bands sit in the summary panel. FCP is a diagnostic rather than a Core Web Vital of its own, and it feeds the PageSpeed score at 10% weight. Lab tools report a single simulated figure while field data reflects the 75th percentile of real visits, so the two rarely match. A slow FCP almost guarantees a slow LCP.
Blocking stylesheets are the usual cause, and the platform decides
The most common thing standing between a page and its first paint is a <link rel="stylesheet"> in the <head>. How often that is fixable is not a property of the team
running the site, it is a property of the builder. From our snapshot of audited sites
(2026-07-23), the share where our proxy found at least one blocking stylesheet worth taking
off the critical path:
| Platform | Sites with blocking stylesheets |
|---|---|
| Bitrix | 29 of 30 |
| Squarespace | 36 of 37 |
| Webflow | 31 of 32 |
| WordPress | 52 of 57 |
| Duda | 4 of 49 |
Duda is the outlier, and it is instructive: that platform already keeps its stylesheets off the blocking path, which is why our gains there come from images and scripts instead. Read these as “of the sites we audited”, not as a measurement of the web.
What delays the first paint
- Render-blocking CSS or JavaScript in the
<head>. The browser will not paint anything until those are fetched and parsed. - Web fonts that hide text until they download. Without
font-display: swap, the first paint waits on the font instead of showing fallback text. - One giant blocking stylesheet. A single
<link>on the critical path holds the paint while it downloads in full. - A slow server. High TTFB pushes the whole timeline back before rendering starts.
- Client-side rendering of the first screen. If the first paint waits on JavaScript to download, parse and execute, FCP fires late.
What you pay for an early paint
font-display: swapfixes blank text, but the swap itself moves text as the web font loads: a direct CLS cost unless the fallback is metric-matched.- Inlining critical CSS removes a request but bloats the HTML the server sends first, nudging TTFB and total transfer up.
- Aggressively deferring stylesheets can briefly show unstyled content, a flash before the CSS applies.
We hold the first two in check with a byte budget on inlined CSS and metric-matched fallback fonts, so a faster FCP does not reintroduce shift or bloat.
Unblocking the head, in code
Let text show with a fallback font, and take non-critical CSS off the critical path. Add
font-display: swap so text paints immediately instead of waiting:
@font-face {
font-family: "Inter";
src: url(/fonts/inter.woff2) format("woff2");
+ font-display: swap;
}
Then load non-critical CSS without blocking the paint: request it as a print stylesheet, then
flip it to all once it arrives.
<link rel="stylesheet" href="/non-critical.css" media="print" onload="this.media='all'">
How we unblock the head
WebSpeed inlines the critical CSS so the first paint does not wait on a network round-trip,
converts blocking stylesheets to async loading where that is safe, defers non-critical
scripts, and adds font-display: swap so text shows immediately in a fallback face.