← Back to Blogs

Advanced Image Optimization Strategies for Improving LCP in Next.js Applications

Fri Jul 10 20264 min read

Hey everyone, I’m Prashuk.

If you’ve ever looked at a Google Lighthouse report and felt personally attacked by that big red "Largest Contentful Paint" (LCP) score, you’re not alone. I’ve spent a lot of time building apps with the MERN stack and Next.js, and honestly, images are almost always the culprit when a site feels "heavy."

Next.js gives us the next/image component, which is great, but just using it isn't a magic fix. I've learned that you have to be intentional about how you handle assets if you want that sub-second load time.

Here is how I actually handle image optimization in my projects.

1. The "Priority" Prop is Not Optional for Heroes

In one of my recent projects—a high-traffic e-commerce storefront—I couldn't figure out why my LCP was lagging even though I was using Next.js images.

I realized I was treating the hero banner just like any other image. By default, Next.js lazy-loads images. This is great for the footer, but terrible for the first thing a user sees.

What worked for me was adding the priority attribute to any image "above the fold." This tells the browser to fetch the image immediately instead of waiting for the JS to kick in.

2. Stop Ignoring the sizes Attribute

I used to be lazy and just skip the sizes prop. Big mistake.

When you don’t define sizes, Next.js often serves a much larger image than necessary because it doesn't know how wide the image will be on different screens. I ran into this issue when a mobile user was downloading a 1200px wide header image on a 390px screen.

Now, I always do something like this:

<Image
  src="/hero.png"
  alt="Project Showcase"
  fill
  priority
  sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
  className="object-cover"
/>

It looks like extra work, but it cut my payload size by nearly 60% on mobile.

3. Use AVIF for Better Compression

Most of us are used to WebP. It’s good, but AVIF is better.

In my experience, AVIF files are often 20% smaller than WebP without any noticeable loss in quality. You can enable this in your next.config.js. It takes a bit more CPU power to compress, but for the user, the speed gain is worth it.

// next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
}

4. The "Blur-up" Pattern for Better UX

Performance isn't just about raw numbers; it's about how the user feels the speed.

I’m a big fan of the placeholder="blur" property. When I was building a portfolio site, I used generated base64 blur strings for my project thumbnails. It stops the layout from jumping around (CLS) and gives the user something pretty to look at while the high-res version loads.

If you're using dynamic images from a CMS, tools like plaiceholder are a lifesaver for generating these on the fly.

5. Fetching Dimensions for Remote Images

A common headache I faced was using images from an external API (like Unsplash or a Headless CMS). Since Next.js needs the width and height to prevent layout shifts, you can't just leave them blank.

Instead of hardcoding values, I started writing a small utility function to fetch image dimensions during getStaticProps. It keeps the code clean and ensures the UI doesn't "jump" when the image finally pops in.

My Best Practices Checklist:

  • Hero Images: Always use priority.
  • Backgrounds: Use CSS object-fit: cover on a Next.js Image instead of a standard div with a background image.
  • SVGs: Don't use next/image for tiny icons. Just inline them or use an icon library to save on HTTP requests.
  • Quality: I usually set quality={75}. Anything above 80 is usually overkill and just adds KBs for no reason.

Wrapping Up

At the end of the day, image optimization isn't about one single "hack." It’s about being disciplined.

The biggest lesson I’ve learned is to test on mobile throttled connections. Your site might look fast on your 100Mbps fiber dev machine, but the real test is a user on 4G in a coffee shop.

Focus on the images that matter most to the user's first impression, and the LCP scores will follow.

What’s your biggest struggle with Next.js performance? Let me know, I'd love to chat about it.

Prashuk