# Above-fold content is explicitly prioritized for loading

- **Pattern:** `ab-001793` (`marketing-page-speed.loading-strategy.above-fold-priority`)
- **Severity:** critical
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001793
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001793)

## Why it matters

Loading the hero image lazily — whether by setting `loading="lazy"` directly or by omitting an explicit priority signal — instructs the browser to deprioritise it until the image enters the viewport. Since the hero is almost always already in the viewport, this creates a paradox: the element that determines LCP is the last one the browser fetches. The result is typically a 1–2s LCP penalty on mobile, which is the difference between 'good' and 'poor' in Google's Core Web Vitals classification system. ISO-25010 time-behaviour defines response time as a critical quality attribute for user-facing interfaces; the above-fold content is exactly where time-behaviour matters most. Google Search Console tracks this at a per-URL level and uses it as a Page Experience ranking input.

## Severity rationale

Critical because lazy-loading the LCP element is a direct 1–2s LCP penalty — the single change most likely to push a marketing page from 'good' to 'poor' CWV classification.

## Remediation

Never apply `loading="lazy"` to the hero image. Use the Next.js `priority` prop or `fetchpriority="high"` on plain `<img>` tags to signal the browser to fetch it immediately.

```tsx
// WRONG — never lazy-load the LCP element
<Image src="/hero.webp" alt="Hero" loading="lazy" />

// CORRECT — Next.js adds fetchpriority=high and <link rel="preload">
<Image
  src="/hero.webp"
  alt="Hero"
  width={1200}
  height={630}
  priority
/>

// For plain img tags
<img
  src="/hero.webp"
  alt="Hero"
  fetchpriority="high"
  decoding="async"
/>
```

Add a manual preload hint in your root layout `<head>` as a belt-and-suspenders signal:

```html
<link rel="preload" as="image" href="/hero.webp" fetchpriority="high" />
```

## Detection

- **ID:** `above-fold-priority`
- **Severity:** `critical`
- **What to look for:** Check that the browser is given explicit signals to prioritize above-fold resources over below-fold ones. Look for: (1) `fetchpriority="high"` on the hero image, (2) `priority` prop on Next.js Image for the hero, (3) `<link rel="preload">` for the hero image in `<head>`, (4) absence of `loading="lazy"` on above-fold images (lazy loading the hero image is a critical mistake), (5) inline or preloaded critical CSS for above-fold styles. Count every resource loaded above the fold and enumerate which use priority hints (fetchpriority, preload, prefetch) vs. which load without prioritization.
- **Pass criteria:** The LCP element (hero image or primary heading) has explicit priority loading (`priority` prop, `fetchpriority="high"`, or `<link rel="preload">`). No above-fold images use `loading="lazy"`. Critical styles are available before first paint. At least 1 implementation must be confirmed.
- **Fail criteria:** Hero image has no priority signal. Above-fold images use `loading="lazy"` (browser deprioritizes them, dramatically increasing LCP). No preload hints for critical resources.
- **Skip (N/A) when:** Project has no above-fold image content (text-only landing page with no hero image).
- **Detail on fail:** `"Hero image in HeroSection.tsx has loading='lazy' — this tells the browser to deprioritize the LCP element. No fetchpriority or preload detected. This alone can add 1-2s to LCP."`
- **Remediation:** This is the single highest-impact fix for LCP:

  ```tsx
  // WRONG — never lazy-load the hero
  <Image src="/hero.webp" alt="Hero" loading="lazy" />

  // CORRECT — priority loads the hero first
  <Image
    src="/hero.webp"
    alt="Hero"
    width={1200}
    height={630}
    priority            // adds fetchpriority=high + preload
  />

  // For plain img tags:
  <img
    src="/hero.webp"
    alt="Hero"
    fetchpriority="high"
    decoding="async"    // decoding async so main thread isn't blocked
  />
  ```

  Additionally, add a preload hint in your layout's `<head>`:

  ```html
  <link rel="preload" as="image" href="/hero.webp" fetchpriority="high" />
  ```

## External references

- iso-25010 performance-efficiency.time-behaviour

Taxons: performance

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