# Image Optimization Is Still Killing Your Core Web Vitals in 2025
By Govind Bajaj · 2026

Tags: web-performance, images, core-web-vitals, next.js, optimization
I audited 23 production sites last month. 19 of them had unoptimized images. The same three mistakes, over and over. Here's the checklist that catches all of them.
I audited twenty-three production sites last month for performance issues.

Nineteen of them had image optimization problems. Not edge cases — fundamental mistakes that directly hurt LCP and CLS. The same three mistakes, repeated across almost every codebase.

This should not still be happening. Next.js has had an Image component since 2020. Every CDN offers automatic optimization. And yet, here we are.

## Mistake 1: Using Raw img Tags

```html
<!-- The most common mistake -->
<img src="/product-photo.jpg" alt="Product" />
```

This single line of HTML does at least four things wrong: serves the full-resolution image regardless of viewport size, uses JPEG instead of WebP or AVIF, causes layout shift because the browser does not know the dimensions until load, and downloads lazily even if the image is above the fold.

The fix with Next.js:

```tsx
import Image from 'next/image'

<Image
  src="/product-photo.jpg"
  alt="Product"
  width={800}
  height={600}
  priority={isHero}
  quality={80}
  sizes="(max-width: 768px) 100vw, 50vw"
/>
```

The Next.js Image component handles format conversion, responsive sizing, and layout shift prevention automatically. If you are using raw img tags in a Next.js app, you are actively making your site slower.

## Mistake 2: Wrong Dimensions or Missing Aspect Ratio

```css
/* Bad: fixed width, auto height causes layout shift */
img {
  width: 100%;
  height: auto;
}
```

When the browser does not know an image's dimensions before it loads, the page layout shifts as the image arrives. This hurts CLS.

Always provide explicit width and height attributes. The browser uses them to reserve space before the image loads:

```tsx
<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
/>
```

For responsive images, use CSS aspect-ratio:

```css
.responsive-image {
  aspect-ratio: 16 / 9;
  width: 100%;
  height: auto;
  object-fit: cover;
}
```

## Mistake 3: Serving Oversized Images

I saw a product thumbnail that was 2400px wide. It displayed at 200px. The browser downloaded 144 times more pixels than it needed.

Use the sizes attribute to tell the browser which image size to download for each viewport:

```tsx
<Image
  src="/product.jpg"
  alt="Product"
  width={2400}
  height={1600}
  sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, 33vw"
/>
```

With a CDN or Next.js Image optimization, the sizes attribute generates responsive srcset entries automatically.

## Mistake 4: Lazy Loading the LCP Element

Browsers default to lazy loading images below the fold. But the Largest Contentful Paint element is above the fold. If it lazy loads, LCP is delayed by the intersection observer detection time.

```tsx
// Good: hero image loads immediately
<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority
/>
```

Only use priority on images visible in the initial viewport. Typically this is one or two images per page.

## Mistake 5: Not Using Modern Formats

WebP images are 25-35% smaller than JPEG at equivalent quality. AVIF is 50% smaller. In 2025, browser support is universal for WebP and strong for AVIF.

```bash
# Convert images to WebP
npx sharp input.jpg --webp --quality 80 --output output.webp
```

## The 5-Point Image Checklist

Before shipping any page, run through this list:

1. Use Next.js Image component (not raw img) — automatic optimization
2. Provide width and height — prevents layout shift
3. Use sizes attribute — serves correctly sized images per viewport
4. priority for above-fold images — do not lazy load your LCP element
5. Modern formats — WebP minimum, AVIF if supported

## Takeaways

- Raw img tags in 2025 are a performance anti-pattern — use Next.js Image
- Always provide explicit width/height to prevent layout shift (CLS)
- The sizes attribute prevents downloading oversized images for the viewport
- priority on above-fold images eliminates lazy-loading delay for LCP
- WebP and AVIF formats reduce image size by 25-50% vs JPEG
- These five checks take 60 seconds and catch the most common image performance problems