# First Contentful Paint budget is met (FCP ≤ 1.8s)

- **Pattern:** `ab-001785` (`marketing-page-speed.core-web-vitals.fcp-budget`)
- **Severity:** medium
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001785
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001785)

## Why it matters

First Contentful Paint at 1.8s or below is Google's 'good' threshold and directly correlates with user-perceived responsiveness as defined under ISO-25010 time-behaviour. FCP above 1.8s is most commonly caused by render-blocking resources: CSS stylesheets in `<head>` that the browser must fully download and parse before it can paint anything. A 120KB unoptimised CSS bundle plus two Google Font `<link>` tags without `font-display` can push FCP past 2.5s on a 4G connection, producing an invisible page that users perceive as broken. Every additional 100ms of FCP correlates with a measurable increase in bounce rate on marketing pages, reducing the number of users who reach the conversion CTA.

## Severity rationale

Medium because FCP delays are user-visible and increase bounce rates, but the impact is partially mitigated when TTFB is already good — the combined failure is more severe than either alone.

## Remediation

Address both CSS weight and font loading to bring FCP under 1.8s. Tailwind's purge configuration eliminates dead CSS; `next/font` self-hosts Google Fonts and applies `font-display: swap` automatically.

```ts
// tailwind.config.ts — verify content paths so purging works
export default {
  content: ['./src/**/*.{ts,tsx}'],
}
```

```tsx
// Replace Google Fonts <link> tags with next/font
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'], display: 'swap' })

export default function RootLayout({ children }) {
  return <html className={inter.className}>{children}</html>
}
```

Audit your CSS output size in `next build` output — if total CSS exceeds 30KB compressed, identify which component libraries are contributing dead weight.

## Detection

- **ID:** `fcp-budget`
- **Severity:** `medium`
- **What to look for:** First Contentful Paint marks when the first piece of content is rendered. FCP > 1.8s usually indicates render-blocking resources, large CSS files, or slow TTFB. Check: (1) are any stylesheets loaded with `<link rel="stylesheet">` in `<head>` without a critical CSS inline approach? (2) is the total CSS bundle large (>50KB unparsed)? (3) does the font loading block paint? (4) is there a Lighthouse budget file (`.lighthousebudget.json`, `budget.json`) that asserts FCP? Count all instances found and enumerate each.
- **Pass criteria:** Critical CSS for above-fold content is inlined or the CSS framework (Tailwind) produces minimal purged bundles. Fonts use `font-display: swap`. No render-blocking external stylesheets. TTFB is within budget (which flows into FCP). At least 1 implementation must be confirmed.
- **Fail criteria:** Large external CSS file blocks rendering. Multiple blocking stylesheets in `<head>`. Fonts without `font-display` cause invisible text during font load, delaying FCP.
- **Skip (N/A) when:** No CSS or styling detected in project.
- **Detail on fail:** `"globals.css imports 3 external Google Font families without font-display:swap. Total CSS is 120KB before Tailwind purging — blocks FCP on slow connections."`
- **Remediation:** Purge and optimize CSS:

  ```tsx
  // Tailwind — ensure purging is configured (content paths)
  // tailwind.config.ts
  export default {
    content: ['./src/**/*.{ts,tsx}'],
    // Tailwind purges unused classes in production
  }

  // Inline critical CSS for above-fold content (advanced)
  // Use next-inline-css or equivalent
  ```

  Use next/font for Google Fonts — it self-hosts and applies `font-display: swap` automatically:

  ```tsx
  import { Inter } from 'next/font/google'
  const inter = Inter({ subsets: ['latin'], display: 'swap' })
  ```

## External references

- iso-25010 performance-efficiency.time-behaviour

Taxons: performance

HTML version: https://auditbuffet.com/patterns/ab-001785
