Web Performance

How to Fix Largest Contentful Paint (LCP) Bottlenecks in Next.js

A deep architectural guide to lowering Largest Contentful Paint (LCP) below 2.5 seconds in Next.js apps by optimizing fetch priority, server streaming, and resource delivery.

Krapton Engineering
Reviewed by a senior engineer4 min read
Share
How to Fix Largest Contentful Paint (LCP) Bottlenecks in Next.js

Even with server-side rendering (SSR) and automated image handling built into modern frameworks, Largest Contentful Paint (LCP) remains one of the hardest Core Web Vitals to master. If your main hero image, headline, or banner block takes longer than 2.5 seconds to fully render on a mobile device, your Google Search visibility will suffer.

In Next.js applications, poor LCP usually isn't a single catastrophic failure. Instead, it's a "death by a thousand cuts" caused by slow server response times (TTFB), hidden layout images, or render-blocking client-side JavaScript. This guide breaks down exactly how to audit your loading timeline and enforce high-performance LCP optimizations in production.


Anatomy of an LCP Milestone

To optimize LCP effectively, you have to stop treating it like a single metric. Google divides LCP into four distinct sub-phases. If you don't know which phase is lagging, you are guessing, not engineering:

  • Time to First Byte (TTFB): The time it takes for the server to return the initial HTML document. Target: < 800ms.
  • Resource Load Delay: The gap between the first byte arriving and the browser discovering the LCP resource (like a hero image). Target: 0ms (immediate discovery).
  • Resource Load Duration: The actual time it takes to download the asset itself. Target: Minimal file sizes via compression.
  • Element Render Delay: The time between the asset finishing its download and actually painting completely on the viewport. Target: < 200ms.

3 Production-Ready Solutions for Next.js

1. Enforcing Fetch Priority on Hero Images

By default, browsers treat images discovered late in the HTML document with a low priority. If your LCP element is an image asset, you must explicitly instruct the browser to download it before any other non-critical resource using the priority flag and the HTML fetchPriority attribute.

import Image from 'next/image';

export default function HeroBanner() {
  return (
    <header className="relative w-full h-[500px]">
      <Image
        src="/images/hero-showcase.jpg"
        alt="Krapton High Performance Systems"
        fill
        priority // Tells Next.js to preload this asset
        fetchPriority="high" // Explicitly signals high network priority to the browser
        sizes="(max-width: 768px) 100vw, 50vw"
        className="object-cover"
      />
      <h1>Architecting Scalable Digital Ecosystems</h1>
    </header>
  );
}

2. Eliminating TTFB Stalls via Progressive Streaming

If your Next.js page relies on heavy, slow API calls directly inside a Server Component, your server won't return a single byte of HTML until all network data settles. This balloons your TTFB and destroys your LCP. Instead, use React <Suspense> boundaries to instantly stream an interactive static shell while data finishes fetching behind the scenes.

import { Suspense } from 'react';
import { SkeletonLoader } from '@/components/ui/loaders';
import SlowDataComponent from '@/components/SlowDataComponent';

export default function PerformanceDashboardPage() {
  return (
    <main className="container mx-auto px-4">
      <h1>Enterprise Metrics Hub</h1>
      
      {/* The static text above streams immediately, preserving a fast initial paint */}
      <Suspense fallback={<SkeletonLoader />}>
        <SlowDataComponent />
      </Suspense>
    </main>
  );
}

3. Zero-Layout-Shift Web Font Loading

If your LCP element is a large textual block (like an H1 headline), loading standard external fonts can cause a Flash of Unstyled Text (FOUT). When the custom font file finally loads, the element shifts, extending the LCP timeline. Use next/font to inject pre-optimized, self-hosted font binaries directly into your CSS layout structure.

import { Plus_Jakarta_Sans } from 'next/font/google';

// Next.js automatically downloads, hosts, and preloads this font at build time
const jakartaSans = Plus_Jakarta_Sans({
  subsets: ['latin'],
  display: 'swap', // Forces fallback system font to show instantly, eliminating render delay
  variable: '--font-jakarta',
});

export default function RootLayout({ children }) {
  return (
    <html lang="en" className={jakartaSans.variable}>
      <body className="font-sans">{children}</body>
    </html>
  );
}

LCP Phase Optimization Matrix

Isolating optimizations against specific architectural layers ensures predictable engineering outcomes. The layout matrix below balances actions against target performance thresholds:

LCP Phase Subcomponent Primary Bottleneck Cause Target Technical Solution
Time to First Byte (TTFB) Blocking backend API database operations Implement dynamic edge caching or UI streaming boundaries.
Resource Load Delay Lazy-loaded images or assets hidden inside JavaScript strings Apply Next.js priority properties to discover assets early.
Resource Load Duration Massive, uncompressed file sizes over low bandwidth connections Enforce multi-format compression pipelines (AVIF/WebP formats).
Element Render Delay Main-thread congestion caused by heavy hydration tasks Defer non-critical interaction scripts away from early paint frames.

Conclusion: Monitor via Real User Metrics (RUM)

Synthetic local testing tools (like running Lighthouse on a high-spec development laptop) rarely reflect the true real-world LCP environment of your users. To truly defend your search ranking metrics, implement continuous field tracking using Chrome's Core Web Vitals Javascript SDK to log production user sessions. Keep your hero images lightweight, decouple heavy data, and watch your positions scale upward on Google's search result indexes.

Next.jsWeb PerformanceCore Web VitalsSEO & GrowthFrontend Architecture
About the author

Krapton Engineering

Krapton Engineering shares practical lessons from shipping production web, mobile, SaaS, and AI systems for growing teams.