Fix First Contentful Paint (FCP): Show Content Faster
Understand First Contentful Paint, why it affects user perception and SEO, and actionable fixes to render your first pixel of content sooner.
First Contentful Paint (FCP) is the user's first sign that your page is actually loading. A blank screen for several seconds sends users reaching for the back button.
Why FCP Matters
- First impression — users judge a site within the first second
- 10% of Lighthouse score — contributes directly to your performance grade
- Leading indicator — slow FCP usually means slow LCP and poor overall experience
| FCP | Rating | User Perception |
|---|---|---|
| ≤ 1.8s | Good | "It's loading!" |
| 1.8–3.0s | Needs Improvement | "Is this site working?" |
| > 3.0s | Poor | reaches for back button |
Common Causes and Fixes
1. Eliminate Render-Blocking Resources
CSS and synchronous JavaScript in <head> block the browser from rendering anything.
Inline critical CSS:
<head>
<!-- Inline above-the-fold styles -->
<style>
body { margin: 0; font-family: system-ui, sans-serif; }
.hero { min-height: 100vh; display: grid; place-items: center; }
</style>
<!-- Load full stylesheet asynchronously -->
<link rel="preload" href="/styles/main.css" as="style"
onload="this.rel='stylesheet'">
</head>
Defer non-critical JavaScript:
<!-- ❌ Blocks rendering -->
<script src="/js/analytics.js"></script>
<!-- ✅ Loads after HTML parsing -->
<script src="/js/analytics.js" defer></script>
2. Optimize Web Fonts
Custom fonts can delay text rendering by seconds:
/* Use font-display: swap to show fallback text immediately */
@font-face {
font-family: "BrandFont";
src: url("/fonts/brand.woff2") format("woff2");
font-display: swap;
}
Preload your critical font files:
<link rel="preload" href="/fonts/brand.woff2" as="font"
type="font/woff2" crossorigin>
3. Reduce Server Response Time (TTFB)
FCP can't start until the HTML arrives. If your server is slow, everything else waits.
- Use a CDN to serve pages from edge locations
- Enable server-side caching — avoid rebuilding pages for every request
- Optimize database queries that run before the HTML response
- Consider static generation (SSG) or ISR in Next.js for content pages
4. Minimize Redirects
Each redirect adds a full network round-trip before the page can start loading:
https://example.com → https://www.example.com → https://www.example.com/en/
That's two extra round-trips. Update your links and canonical URLs to point to the final destination.
5. Reduce HTML Document Size
Large HTML documents take longer to download and parse:
- Remove inline SVGs that aren't visible above the fold
- Defer rendering of below-the-fold content with lazy loading
- Enable gzip or Brotli compression on your server
# Nginx — enable Brotli compression
brotli on;
brotli_types text/html text/css application/javascript;
6. Preconnect to Required Origins
If your page needs resources from other domains, start the connection early:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://cdn.example.com" crossorigin>
This eliminates DNS lookup + TCP + TLS time from the critical path.
Measuring FCP
In JavaScript
new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.name === "first-contentful-paint") {
console.log("FCP:", entry.startTime, "ms");
}
}
}).observe({ type: "paint", buffered: true });
In Lighthouse
Run npx lighthouse https://yoursite.com --only-categories=performance and check the FCP metric in the output.
Quick Wins Checklist
- Inline critical CSS and async-load the rest
- Add
font-display: swapto all@font-facerules - Preload critical fonts and preconnect to third-party origins
- Add
deferto non-critical scripts - Eliminate unnecessary redirects
- Enable Brotli or gzip compression
- Target TTFB under 600ms
Ready to stop wasting ad spend?
Track your landing page performance, monitor Core Web Vitals, and calculate exactly how much slow pages cost you.
Start Free — No Credit Card