Skip to content

Why Is My Next.js LCP High? Fix Image Optimization Now

I noticed my Next.js app had a Largest Contentful Paint (LCP) score of over 4 seconds. Google considers anything above 2.5 seconds as “needs improvement.” This was hurting my Core Web Vitals and likely my search rankings.

After investigating, I found the culprit: a 5.2MB hero image loading without any optimization.

The Problem: Unoptimized Images

I was using a regular <img> tag for my hero image:

components/Hero.jsx
// This was my mistake
<img src="/hero.png" alt="Hero image" />

The browser downloaded the entire 5MB file before LCP could fire. On slower connections, this meant 8-10 seconds of loading time.

I checked the Network tab in DevTools and confirmed:

  • File size: 5.2MB
  • Format: Uncompressed PNG
  • No responsive sizing

This pattern is common in AI-generated Next.js apps. I found multiple developers on Reddit reporting the same issue—vibe-coded apps shipping massive images without optimization.

Why High LCP Matters

LCP directly impacts three things:

  1. SEO rankings - Google uses Core Web Vitals as ranking factors
  2. User experience - Users abandon sites loading over 3 seconds
  3. Hosting costs - Platforms like Vercel bill by bandwidth

My 5MB image was costing me on all three fronts.

The Solution: Next.js Image Component

Next.js provides a built-in Image component that handles optimization automatically. It resizes, compresses, and converts images to modern formats like WebP and AVIF.

Here’s the corrected code:

components/Hero.jsx
import Image from 'next/image'
export default function Hero() {
return (
<Image
src="/hero.png"
alt="Hero image"
fill
sizes="100vw"
priority
quality={85}
className="object-cover"
/>
)
}

Let me explain each prop:

  • fill - The image fills its parent container (requires position: relative on parent)
  • sizes="100vw" - Tells Next.js the image displays at full viewport width
  • priority - Preloads this image (use for above-fold images only)
  • quality={85} - Compression quality (default is 75, I bumped it slightly)

Common Mistakes to Avoid

I made several mistakes before getting this right:

Mistake 1: Using regular <img> tags

BadExample.jsx
// BAD: No optimization at all
<img src="/hero.png" alt="Hero" />

Mistake 2: Forgetting the sizes attribute

Without sizes, Next.js cannot generate the correct srcset. The browser might download a larger image than needed.

MissingSizes.jsx
// BAD: No sizes attribute
<Image src="/hero.png" alt="Hero" fill />

Mistake 3: Not using priority on hero images

Above-fold images should load immediately. Without priority, Next.js lazy-loads them.

MissingPriority.jsx
// BAD: Hero image will be lazy-loaded
<Image src="/hero.png" alt="Hero" fill sizes="100vw" />

Mistake 4: Using unoptimized prop

Some developers disable optimization to “fix” errors:

Unoptimized.jsx
// BAD: Defeats the purpose
<Image src="/hero.png" alt="Hero" unoptimized />

Don’t do this. Fix the underlying configuration issue instead.

Configuring Remote Images

If your images come from external sources, configure them in next.config.js:

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
pathname: '/images/**',
},
],
},
}
module.exports = nextConfig

Verifying Optimization Works

After making changes, I verified in Chrome DevTools:

  1. Open Network tab
  2. Reload the page
  3. Find your image request
  4. Check the response headers for content-type: image/webp

My hero image went from 5.2MB PNG to 180KB WebP. That’s a 96% reduction.

LCP dropped from 4.2 seconds to 1.1 seconds.

Quick Checklist

Before deploying your Next.js app:

  • Replace all <img> tags with <Image> from next/image
  • Add sizes attribute to responsive images
  • Add priority to above-fold images
  • Verify image format in Network tab (should be WebP or AVIF)
  • Check LCP in Lighthouse (aim for under 2.5s)

In this post, I shared how I fixed high LCP in my Next.js app by properly using the Image component. The key changes were switching from <img> to <Image>, adding sizes and priority props, and verifying the optimization in DevTools.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments