Reference guide · images · Published 2026-08-16 · 3 min read
Lazy loading with srcset
Combine lazy loading with srcset and sizes: what the browser defers, the candidates to keep eager, and the LCP-safe pattern.
- ·How defer works
- ·Correct sizing
- ·The LCP boundary
What loading="lazy" defers in a srcset
loading="lazy" on an <img> with srcset and sizes defers the whole selection: the browser does not compute which candidate to download until the image is near the viewport. Once the load triggers, the srcset algorithm runs with the current viewport and DPR, picks a candidate, and starts the fetch. The lazy-ness does not change which candidate wins; it only delays when the browser asks.
That makes the pair safe to combine, so the only real concerns are the ones that apply to lazy-loaded images generally:
- the LCP candidate must stay eager;
- the layout box must be reserved (via
width/heightor a CSS aspect ratio) or the page shifts when the deferred image loads; - the candidate set must still include the sizes your intermediate widths use, because a layout that changed after the image was authored (e.g.
sizesnow says 50vw but the set stops at 800w) downloads the wrong weight anyway.
The safe combined markup
<img
srcset="card-400.webp 400w,
card-800.webp 800w,
card-1200.webp 1200w"
sizes="(min-width: 900px) 33vw, (min-width: 500px) 50vw, 100vw"
src="card-800.webp"
width="800" height="500"
loading="lazy"
decoding="async"
alt="...">
width and height here reserve the aspect ratio 800x500, so a deferred candidate does not change the layout when it arrives. The browser selects among the candidates lazily and downloads the smallest suitable one when the image scrolls near.
The LCP boundary
Any <img> that is or can be the LCP candidate must not be lazy. The common failure: a "LCP potential" image (a first-section card in a responsive grid) that has loading="lazy". On a phone the first card occupies the initial viewport, so the browser has already picked it; with loading="lazy" it waits until the viewport is near, which delays the LCP. Rule: the image in the first viewport keeps eager loading, and only images below the fold take loading="lazy", as described in the LCP guide.
The same rule applies with fetchpriority="high": do not combine a lazy loading with a high fetchpriority on the same img; they fight (one says load early at high priority, the other says defer). Pick one behaviour per image.
CLS on the grid
Responsive images produced a layout-shift trap when mobile layouts change the aspect ratio between candidates. The width and height attributes reserve the intrinsic aspect ratio of the largest candidate, and CSS aspect-ratio (or the intrinsic ratio) stops the box collapsing when the lazy image fills. The layout shift fix covers the fix pattern generally.
Verify the combination
In DevTools Network, scroll a page with a lazy srcset grid to the fold and check that:
- no request for below-the-fold candidates is issued until the scroll nears them;
- the URL fetched for the LCP image (still eager) matches what
sizeswould pick; - no eager candidate is fetched twice (a Lazy candidate duplicated by the
srcvalue is the classic double-request).
The preload hero aside explains why mismatches between sizes and the layout cause duplicate downloads even with lazy-loading.
Prevention
Use loading="lazy" only below the fold, keep fetchpriority and loading mutually exclusive, reserve width/height on every image, and make sure the sizes you ship reflects the real CSS layout at every breakpoint. That combination keeps a responsive gallery fast without hurting LCP or CLS, on any device.