# First Contentful Paint: what it measures and what moves it

You fix First Contentful Paint by reducing back end wait, unblocking the first render and sorting fonts. This guide shows what FCP measures, why it sits in Lighthouse, how it relates to LCP, and a quick routine you can run on any page.

Updated 2026-09-14 · Source: https://porteur.ai/guides/first-contentful-paint

## What First Contentful Paint measures

First Contentful Paint is the time from navigation to the first text or image draw. It is the moment something real appears, not a blank screen.

- Good as of 2026: up to 1.8 s
- Needs work: 1.8 s to 3 s
- Poor: above 3 s

FCP is not a Core Web Vital. It is part of Lighthouse’s Performance score, weighted 10 percent. It does not appear in the Search Console Core Web Vitals report.

You will see two kinds of data. Field data, from real Chrome users over 28 days at the 75th percentile. Lab data, a single Lighthouse run on a simulated mid-range phone over throttled 4G. The two can disagree. Field data wins for Search and for prioritisation.

## Why FCP matters on a small site

Users feel the page has started when FCP lands early. It reduces the blank screen time while the rest builds. It sets the tone before LCP arrives.

You do not chase 100. You ship fast first paint on the pages that get visits: the home page, /pricing, /guides/getting-started. A quick first draw lowers drop-offs on slow mobile connections and older devices.

## How FCP relates to LCP, INP and CLS

FCP is the first visible content. LCP is the largest above-the-fold content: a hero image, a big heading or a video poster. FCP is first, LCP is the big thing you care about for rankings.

| Metric | What it measures | Good threshold |
| --- | --- | --- |
| Largest Contentful Paint (Core Web Vital) | Time to the largest image, video poster or text block in the viewport | Up to 2.5 s |
| Cumulative Layout Shift (Core Web Vital) | Unexpected layout movement during a session window | Up to 0.1 |
| Interaction to Next Paint (Core Web Vital) | Slowest interaction’s delay to next paint over a visit | Up to 200 ms |
| First Contentful Paint (Lighthouse only) | Time to first text or image draw | Up to 1.8 s |
| Time to First Byte | Time to first response byte from the server | Up to 0.8 s |

INP replaced First Input Delay in March 2024. Lighthouse cannot interact, so Total Blocking Time is its lab proxy for INP and carries 30 percent of the score. Keep that in mind when you balance work.

## What actually moves FCP

Three levers move FCP on most product sites: back end wait, render-blocking resources, and fonts. Fix them in this order.

- Time to First Byte: long server work or slow networks delay the first paint.
- Render-blocking resources: CSS in the head blocks rendering, synchronous scripts block parsing.
- Fonts: the first text cannot draw until the font decision is clear, and a late web font can blank text.

> Do not lazy-load anything visible at first paint. The hero image and first copy must load immediately.

## A quick diagnosis routine for any page

1. **Open PageSpeed Insights for your URL** Check the Mobile tab first. Look at the field section at the top. If FCP shows in the distribution, note the 75th percentile. If there is no field data, use Lighthouse lower down but treat it as lab only.
2. **Compare with LCP and TTFB** If LCP is slow and TTFB is high, start with the server. If FCP is slow but TTFB is fine, look for blocking CSS and fonts.
3. **Read Lighthouse opportunities** Under Diagnose performance issues, expand Render-blocking resources, Reduce unused CSS and Eliminate render-blocking resources. Expand Preload key requests and Ensure text remains visible during webfont load.
4. **Inspect the head of the document** View-source on yourpage.com. Count stylesheets and synchronous scripts in the head. Note @import in CSS. Spot any Google Fonts CSS URL and whether you preload fonts.
5. **Check the first paint content** What draws first? A logo SVG, a nav, or a heading. Make sure the markup for that content is in the HTML, not injected by JavaScript.
6. **Run a local throttle test** Use Chrome DevTools, Performance panel. Simulate a mid-range phone and slow 4G. Record once. Look at the first paint and long tasks around it.

A page that is fixed will show FCP close to TTFB plus a small render time, stable across runs on mobile. The first text appears before any heavy scripts execute.

## Reduce Time to First Byte

TTFB is the time from request start to the first byte of the response. It includes DNS, TCP and TLS, redirects, and your server’s work. It sets the earliest possible FCP.

- Cache or pre-render the HTML on the edge. Serve the shell fast even if data loads later.
- Use a CDN close to users. Enable HTTP/2 or HTTP/3 and keep-alive.
- Remove redirect chains. Send the final URL in all links and sitemaps.
- Profile slow back end code. Cut database round trips and serial API calls.
- Ship 103 Early Hints for critical CSS and fonts when your stack supports it.

On yourproduct.com/pricing, a drop in TTFB from 1.6 s to 0.5 s often moves FCP by about a second, because the browser can start layout and paint sooner.

## Unblock the first render

Stylesheets in the head block first paint. Synchronous scripts block parsing. Your goal is to inline only what is needed for the above-the-fold view, and defer the rest without breaking the design.

- Inline critical CSS for the hero and nav. Under about 14 kB compressed is a common ceiling for the first chunk.
- Load non-critical CSS with media=print and swap onload, or use disabled until onload patterns. Remove @import chains.
- Defer or async all scripts that do not set up the first paint. type=module defers by default. Move any remaining blocking scripts to the end of body.
- Remove unused CSS. Ship fewer kilobytes and fewer files. A single merged CSS file for critical styles is fine.
- Avoid JavaScript-inserted first content. Server-render the first heading and nav so the browser can paint without waiting for hydration.

/guides/getting-started with four CSS files in the head and a synchronous analytics script will paint late. Inline the header styles, defer the script, and load the rest of the CSS after onload. The first H1 will draw sooner, and FCP will drop under 1.8 s on mobile in lab runs.

## Make fonts stop blocking paint

Web fonts delay text. The browser must decide which face to use and fetch it. If the font arrives late and you block rendering, FCP suffers. If you swap too late, you get a flash of invisible text.

- Use font-display: swap or optional so fallback text draws at FCP. Only the first viewport needs this guarantee.
- Preload the one font file used above the fold. rel=preload as=font crossorigin. Point it at the exact WOFF2 file.
- Self-host fonts in WOFF2. A third-party host adds DNS, connection and TLS before bytes flow.
- Subset by unicode-range so the file the first paint needs is small. A variable font can replace several files, but still subset.
- Consider a system font stack for the UI. It costs no network trip and paints early.
- If the swapped font shifts layout, match metrics. Use size-adjust and ascent-override on the fallback to keep CLS low.

On yourproduct.com, if your first visible copy is the H1, preload the regular weight that renders it. Set font-display: swap. The first paint will not wait for a 90 kB font from a third-party CSS URL.

## Do third-party scripts affect FCP

They can. A synchronous tag in the head blocks parsing. Even deferred scripts compete for bandwidth before the first paint if you start many at once. A heavy tag manager container can inject CSS and JS that add work before paint.

- Remove scripts nobody uses. Verify in your analytics and tag manager.
- Load on interaction when possible. Use a facade for video embeds.
- Defer until after load. Preconnect to origins that must start early, but be sparing.
- Keep the tag manager container small and split by environment.

## How to check FCP the right way

PageSpeed Insights shows field data at the top when there is enough traffic, and a Lighthouse run below. Scores vary between runs. Use field data to judge real users and pass or fail of Core Web Vitals. Use Lighthouse to find fixes. The Lighthouse score itself is not a ranking factor.

- Search Console’s Core Web Vitals report reads field data per URL or origin. It shows LCP, CLS and INP only.
- CrUX field data comes from opted-in Chrome users on Android and desktop, not iOS.
- Mobile-first indexing is complete. Prioritise mobile FCP and LCP.

## A worked example: moving a slow FCP

Say /pricing has FCP 3.2 s on Mobile in Lighthouse, TTFB 1.4 s, LCP 4.6 s. You see three CSS files in the head, a Google Fonts stylesheet, and a synchronous A/B test script. The hero image is marked loading=lazy.

1. **Fix the server wait** Enable HTML caching for /pricing and edge cache it. TTFB falls to 0.6 s.
2. **Inline critical CSS** Inline styles for the header, hero and first section. Load the rest after onload. Remove @import chains. Fewer requests hit the head.
3. **Defer scripts** Move the A/B test off the critical path or run it as deferred with a fast no-flash variation CSS. Defer analytics too.
4. **Sort fonts** Self-host the Inter regular WOFF2, preload it, and set font-display: swap. Add size-adjust to match fallback.
5. **Fix the hero** Remove loading=lazy and add fetchpriority=high to the hero image. If it is a CSS background, add a preload link.

After these changes the next Lighthouse run shows FCP about 1.6 s and LCP about 2.5 s. Field data will follow if traffic is steady, as it needs 28 days and the 75th percentile to move.

## Questions

### What is considered a good FCP score

Good FCP is up to 1.8 seconds. Between 1.8 and 3 seconds needs work, above 3 seconds is poor. Treat this as a user comfort target, not a ranking factor.

### Is First Contentful Paint a Core Web Vital

No. FCP is not a Core Web Vital. It is part of the Lighthouse Performance score at 10 percent. Core Web Vitals as of 2026 are LCP, CLS and INP.

### How do I improve FCP fast

Cut TTFB by caching HTML and using a CDN. Inline critical CSS and defer other CSS and scripts. Use font-display: swap, preload the first font, and self-host WOFF2. These three changes move most pages.

### How does FCP differ from LCP

FCP is the time to the first visible content of any size. LCP is the time to the largest above-the-fold element. FCP comes first. LCP is the Core Web Vital that matters for Search.

### Why do Lighthouse and PageSpeed Insights disagree

Lighthouse is one simulated run. PageSpeed Insights shows that plus field data from real Chrome users. Scores vary between runs. Use the field section for real-world judgement and the audits below it for fixes.

### Does INP affect FCP fixes

Indirectly. You still defer heavy scripts and break long tasks for INP, which also helps the first paint by freeing the main thread. INP’s good threshold is up to 200 ms and it replaced FID in March 2024.

## Read next

- [Core Web Vitals for a product site: the three numbers](https://porteur.ai/guides/core-web-vitals): The product founder’s guide to LCP, CLS and INP: what Google measures, why phones decide the pass, common causes, and how to test and fix.
- [Largest Contentful Paint: what slows it and what fixes it](https://porteur.ai/guides/largest-contentful-paint): See what usually counts as LCP, what makes it slow, how to fix it in order, and how to read it in Lighthouse and field data.
- [Time to first byte: the delay every other metric inherits](https://porteur.ai/guides/time-to-first-byte): TTFB sets the pace for every other speed metric. See what it includes, how to test it in field and lab, the causes on product sites, and the fixes.
- [Render-blocking resources: what blocks the first paint and how to unblock it](https://porteur.ai/guides/render-blocking-resources): Stop CSS and synchronous scripts from blocking first paint. Read the Lighthouse audit and fix in order: defer, inline critical CSS, split CSS, and handle fonts.
- [Web fonts and page speed: load one face, and load it first](https://porteur.ai/guides/web-fonts-and-page-speed): Ship crisp type without slowing first paint or shifting layout. Choose one fast path, preload the face above the fold, and stop the swap from moving text.
- [How to read PageSpeed Insights: field data first, then the score](https://porteur.ai/guides/how-to-read-pagespeed-insights): Start with field data, not the score. Learn what Google uses, why scores vary, and how to turn a PageSpeed Insights run into a clear order of fixes.
- [E-E-A-T](https://porteur.ai/glossary/e-e-a-t): E-E-A-T means Experience, Expertise, Authoritativeness and Trustworthiness. What it means for a small product site, and how to show it.

Paste your URL to see how your first paint stacks up against rivals and which of TTFB, blocking CSS or fonts holds it back, in about thirty seconds, free. Free check: https://porteur.ai/
