# Image optimization: the four decisions that matter

> Serve images at the size they actually render, convert to WebP, compress to about 80% quality, and preload only the LCP image while lazy-loading the rest. A hero image is the single most common cause of a slow Largest Contentful Paint.

Source: https://rankcert.com/blog/image-optimization-guide
Published: 2026-08-29 · Updated: 2026-09-02

---


Images are usually 60 to 70% of a page's transferred bytes and the most common cause of a failing Largest Contentful Paint. Four decisions cover almost all of it.

## 1. Dimensions: serve what you display

The most wasted bytes on the web are pixels nobody sees. A 4000px photograph displayed in a 1200px container wastes roughly 90% of its payload - the browser downloads every byte, then throws most of them away during scaling.

Work out the largest size the image actually renders at, double it for retina if it is a hero, and resize to that. Nothing wider.

Free tool: [Image Resizer](https://rankcert.com/tools/image-resizer) - Resize PNG, JPG, WebP and GIF images to exact pixel dimensions with aspect ratio locked. Runs entirely in your browser - no upload, no queue, no watermark.

For images that render at different sizes across breakpoints, use `srcset` and let the browser pick:

```html
<img
  src="/hero-1200.webp"
  srcset="/hero-600.webp 600w, /hero-1200.webp 1200w, /hero-2400.webp 2400w"
  sizes="(max-width: 768px) 100vw, 1200px"
  width="1200" height="630" alt="..."
/>
```

The `sizes` attribute is the part people omit, and without it the browser assumes the image is full viewport width and picks the largest candidate on every screen.

## 2. Format: WebP unless you have a reason

- **WebP** - the default. 25 to 35% smaller than equivalent JPEG, supports transparency, supported by every current browser.
- **JPEG** - photographs where you need maximum compatibility with old clients.
- **PNG** - only when you need lossless or the image has very few colours. Screenshots of text, logos, diagrams.
- **AVIF** - compresses better than WebP but encodes slowly and support is thinner. Ship it as an extra `<source>` if your build can generate it.
- **SVG** - anything vector. Logos, icons and diagrams should never be raster.

Free tool: [PNG to WebP](https://rankcert.com/tools/png-to-webp) - Convert PNG and JPG images to WebP with a quality slider, and see exactly how many bytes you saved before downloading.

## 3. Compression: 80%, then look

For lossy formats, 80% quality is the usual sweet spot - typically a 60 to 80% size reduction with no visible difference on a photograph.

The right method is not to trust a number: move the slider down until you can first see a difference, then step back one notch. Gradients, skies and skin tones show artefacts first, so judge on those regions rather than on detailed textures which hide them.

Free tool: [Image Compressor](https://rankcert.com/tools/image-compressor) - Compress JPG and PNG images with a live quality slider and see the exact size saving before you download. Everything runs in your browser.

Targets worth hitting: a hero under 200KB, everything else under 100KB. Anything over about 500KB is a Core Web Vitals problem on its own.

## 4. Loading: preload one, lazy-load the rest

```html
<link rel="preload" as="image" href="/hero.webp" fetchpriority="high" />
```

Preload **only** the LCP image. Preloading several defeats the point - you are telling the browser everything is the priority, which means nothing is.

Everything below the fold gets `loading="lazy"`. Everything above it must not, because lazy-loading your LCP image delays it by a full round trip and is a common self-inflicted wound.

And set `width` and `height` on every image. It costs nothing and it is the single biggest fix for Cumulative Layout Shift - without them the browser cannot reserve space, so the page jumps when each image arrives.

## The checklist

1. Resized to the largest rendered size, not the original.
2. Converted to WebP, with `srcset` where the size varies.
3. Compressed to roughly 80%, checked on a gradient.
4. LCP image preloaded with `fetchpriority="high"`, never lazy.
5. Everything below the fold `loading="lazy"`.
6. `width` and `height` on every single one.
7. Real `alt` text, or `alt=""` if genuinely decorative.

<Callout>
If your LCP is failing, the cause is an image roughly nine times out of ten. Check its transferred size and its rendered size before touching anything else on the page.
</Callout>

<Cta />
