# Large image files

> Multi-hundred-KB images blow your LCP and mobile data budget. Compress to WebP/AVIF, resize to display size, and serve from an image CDN.

_Category: Performance · Detector `large-images` · Severity: error_

A single unoptimized hero image can be heavier than all your JavaScript combined, and it usually sits right in the critical path as the LCP element — so a fat image directly slows the metric Google measures your loading speed on. On mobile data it’s money out of the user’s pocket. AI-built pages routinely embed full-resolution PNGs and un-compressed exports.

## Symptoms

- One image is several hundred KB to multiple MB in the Network panel
- Slow LCP (Largest Contentful Paint), especially on mobile
- A PNG used where a compressed WebP/AVIF would be a fraction of the size
- The hero takes a visible beat to appear on a throttled connection

## How VibeCheck detects it

The `large-images` detector flags this live in the browser and reports it to the widget's Problems list — and to your coding agent over MCP.

- **Issue string:** `Large image: 512KB`
- **Threshold:** ≥ 500KB transferred (warning), ≥ 1,024KB (error) — measured via Resource Timing

## Root causes

- Uncompressed PNG/JPEG exported straight from a design tool
- A full-resolution original served where a resized copy would do
- No modern format (WebP/AVIF), which compress far better than PNG/JPEG
- No image CDN doing on-the-fly compression and format negotiation

## The fix

Compress and re-encode heavy images to WebP or AVIF (typically 30–80% smaller than PNG/JPEG at the same quality), resize them to no more than 2× their displayed dimensions, and ideally serve them through an image CDN that negotiates format and size per request. Use `<picture>` to offer AVIF with fallbacks.

### Steps

1. Resize the source to at most 2× the size it’s displayed at
2. Re-encode to AVIF/WebP with a quality around 75–80
3. Serve via `<picture>` with fallbacks, or through an image CDN

_Offer AVIF → WebP → JPEG fallback_

```html
<picture>
  <source type="image/avif" srcset="/hero.avif" />
  <source type="image/webp" srcset="/hero.webp" />
  <img src="/hero.jpg" width="800" height="450" alt="Hero" />
</picture>
```

_Batch-compress with sharp_

```bash
npx sharp-cli -i hero.png -o hero.avif --avif quality=75
```

## Framework-specific fixes

### Next.js

`next/image` compresses and converts to AVIF/WebP automatically and serves per-device sizes — pointing it at a large source and letting it optimize is usually the whole fix.

```tsx
import Image from 'next/image'
// Next generates optimized AVIF/WebP variants at request time.
<Image src="/hero-original.png" width={800} height={450} alt="Hero" />
```

[Next.js docs](https://nextjs.org/docs/app/api-reference/components/image)

### Vue

On Nuxt, `@nuxt/image` compresses and reformats at build/request time. Plain Vue: pre-compress and use `<picture>` as above.

```vue
<template>
  <NuxtImg src="/hero-original.png" format="avif,webp" width="800" height="450" alt="Hero" />
</template>
```

[Vue docs](https://image.nuxt.com/)

### Vanilla JS

Pre-compress with sharp/squoosh in your build, then serve AVIF/WebP with a `<picture>` fallback. Or put an image CDN in front and pass width/format query params.

```bash
# one-off or in your build step
npx @squoosh/cli --avif '{"quality":75}' hero.png
```

## FAQ

### What image size is acceptable?

Aim to keep individual images well under 200KB where you can. VibeCheck warns at 500KB and errors at 1MB — past that you’re almost certainly serving an un-resized or un-compressed original.

### AVIF or WebP?

AVIF compresses better but encodes slower and has slightly less universal support; WebP is faster and near-universal. Offer AVIF first with a WebP (then JPEG) fallback via `<picture>`, and you get the best of both.

### Does this affect SEO?

Yes, indirectly — a heavy hero image usually is your LCP element, and LCP is a Core Web Vital Google uses in ranking. Lighter images mean a faster LCP and a better page-experience signal.

## Related problems

- [Unoptimized images](https://vibecheck.wcgw.fun/fix/unoptimized-images.md) — Performance
- [Cumulative layout shift (CLS)](https://vibecheck.wcgw.fun/fix/cumulative-layout-shift.md) — Performance
- [Large JavaScript bundles](https://vibecheck.wcgw.fun/fix/large-javascript-bundles.md) — Performance
- [Images missing alt text](https://vibecheck.wcgw.fun/fix/missing-image-alt-text.md) — Search visibility

---

Fix guide from VibeCheck — https://vibecheck.wcgw.fun/fix/large-image-files. Full site index for LLMs: https://vibecheck.wcgw.fun/llms.txt
