# Image optimization

> Keep a Shoplazza Theme fast: request the right image size with img_url, serve responsive srcset candidates, prevent layout shift, and lazy-load offscreen images.

Images are often the largest assets on a storefront page. Optimizing them keeps merchants' stores fast and improves the experience for their customers. Follow these practices when you render images in your theme.

## Serve appropriately sized images

Don't render full-size source images. Use the [`img_url`](/docs/theme/references/liquid/filters/media#img_url) filter with a size so the requested image matches its display size:

```liquid title="Code"
{{ product.image | img_url: '600x' }}
```

Request only the width or height you need and let the other dimension scale proportionally. For high-density (retina) screens, use the `scale` parameter to serve a sharper image:

```liquid title="Code"
{{ product.image | img_url: '600x', scale: 2 }}
```

## Serve responsive images with srcset

A single image size can't be optimal for every screen. Provide several widths with `srcset` and let the browser pick the best one for the device's viewport and pixel density. Build each candidate with `img_url`:

```liquid title="Code"
<img
  src="{{ product.image | img_url: '600x' }}"
  srcset="{{ product.image | img_url: '300x' }} 300w,
          {{ product.image | img_url: '600x' }} 600w,
          {{ product.image | img_url: '900x' }} 900w"
  sizes="(max-width: 600px) 100vw, 600px"
  width="{{ product.image.width }}"
  height="{{ product.image.height }}"
  alt="{{ product.image.alt | escape }}">
```

Here's what each part does:

- **`src`** — a fallback image for browsers that don't support `srcset`.
- **`srcset`** — the candidate list. Each entry is an image URL followed by a width descriptor: `300w` declares that the image is 300 pixels wide. You supply several widths and let the browser choose.
- **`sizes`** — how much space the image will occupy once laid out, so the browser can pick a candidate before it knows the image's real dimensions. Here, `(max-width: 600px) 100vw, 600px` means "full viewport width on screens up to 600px, otherwise a fixed 600px."
- **`width` and `height`** — the image's intrinsic pixel dimensions, which reserve space and prevent layout shift (see the next section).
- **`alt`** — the text alternative, escaped so any quotes in the text don't break the attribute.

The browser combines the `srcset` widths with `sizes` and the device's pixel density to download just one appropriately sized image.

## Reserve space to prevent layout shift

When an image loads without declared dimensions, surrounding content jumps as the image appears, which hurts [Cumulative Layout Shift](https://web.dev/cls/). Set `width` and `height` on the `<img>` element so the browser reserves space before the image loads. The [image object](/docs/theme/references/liquid/objects/image) exposes these values:

```liquid title="Code"
<img
  src="{{ product.image | img_url: '600x' }}"
  width="{{ product.image.width }}"
  height="{{ product.image.height }}"
  alt="{{ product.image.alt | escape }}">
```

## Lazy-load offscreen images

Add `loading="lazy"` to images that appear below the fold so the browser defers loading them until they're needed:

```liquid title="Code"
<img src="{{ product.image | img_url: '600x' }}" loading="lazy" alt="{{ product.image.alt | escape }}">
```

Don't lazy-load images that are visible when the page first renders, such as a hero banner or the main product image. Lazy-loading above-the-fold images delays your [Largest Contentful Paint](https://web.dev/lcp/).

## Preload the main above-the-fold image

For the largest image visible on initial load, add a preload hint in the page `<head>` so the browser fetches it sooner:

```liquid title="Code"
<link rel="preload" as="image" href="{{ product.image | img_url: '1080x' }}">
```

Preload only this one image — preloading too many resources competes for bandwidth and slows the page down. For the [`preload_tag`](/docs/theme/references/liquid/filters/html#preload_tag) filter and other resource hints, see [Performance](/docs/theme/best-practices/performance).
