Adding loading="lazy" to the image that becomes your Largest Contentful Paint element delays it. On a bare test page the cost was about 20ms. With a 600ms render-blocking stylesheet in front, the lazy hero finished at 3,524ms against 2,912ms for the same image without it. Lazy-load images below the fold; leave the first, biggest image alone.

Key takeaways

  • Lazy-loading the LCP image delays LCP. web.dev's data across all pages in the Chrome UX Report shows a median 75th-percentile LCP of 2,922ms without lazy loading and 3,546ms with it, though it notes this is correlation, not proof.
  • On a bare page the cost was small: about 20ms (2,924ms against 2,904ms median, five runs each, emulated slow connection).
  • Behind a slow stylesheet it was large: +612ms (3,524ms against 2,912ms), almost exactly the stylesheet's delay.
  • fetchpriority="high" matched the default in both tests. It did not make the image faster here; its benefit shows when other requests compete for the connection.
  • The page's load event does not wait for lazy images. Measure at load and you will miss the image entirely, which is how the first run of this test went wrong.
  • The rule: lazy-load below-the-fold images, never the first one, and check that no plugin or template adds the attribute to everything.

What the published data says first

Before the test, the evidence from people with far more traffic than a test page. web.dev's article on lazy-loading and LCP reports both observational and experimental results:

Figures reported by web.dev. The first two rows are correlations; the A/B rows are experiments.
Measurement Without lazy loading With lazy loading
Median 75th-percentile LCP, all pages (CrUX)2,922ms3,546ms
Same, WordPress pages3,495ms3,768ms
A/B test, archive pages, desktop1,759ms (disabled)2,029ms
A/B test, archive pages, mobile1,403ms (disabled)1,657ms

The same article found single pages differed by only 2 to 4 percent, so the effect is not uniform, and that lazy loading roughly halved image bytes on archive pages (577 KB against 1,173 KB). The trade is real: fewer bytes for pages where images are off screen, a later LCP where an image is the first thing people see.

The test

One page: a header, a single 527 KB image sized to the full width, and a line of text. Three variants of the image tag (default, loading="lazy", fetchpriority="high"), each loaded five times in a fresh browser context, with LCP read from a PerformanceObserver. Network conditions were emulated through the Chrome DevTools protocol: no throttling, then roughly 150ms round-trip and 1.6 Mbps.

Median LCP in milliseconds over five runs. Chromium 141, local server.
Condition Default loading="lazy" fetchpriority="high"
No throttling364844
Slow connection2,9042,9242,904
Slow connection, plus a 600ms render-blocking stylesheet2,9123,5242,916

On a bare page, lazy loading cost about 20ms, which is within what you would shrug off. Add a stylesheet that takes 600ms to arrive and the lazy image finished 612ms later than the default, while the default barely moved. One run-level detail worth knowing: the page's load event fires without waiting for a lazy image. The first attempt at this test stopped measuring at load, recorded an LCP of 180ms for the lazy page, and was wrong; the image arrived about 2.7 seconds later.

Why it happens

What is documented and what is inferred from the measurements.
Claim Status Basis
Lazy-loading an above-the-fold image can delay LCPDocumentedweb.dev's data and A/B tests above, plus the measurements here
The delay in the slow-stylesheet case matches the stylesheet's delayMeasured+612ms against a 600ms delay
A normal image is requested as soon as the HTML is parsed; a lazy one waits until layout is knownInferredConsistent with the results; the browser's request ordering was not traced

The inference is the simple one. A normal image is found early and fetched in parallel with the stylesheet. A lazy image has to wait until layout shows whether it is in view, and layout waits for the stylesheet. Anything that delays layout, such as a slow stylesheet or a long task on the main thread, therefore delays the lazy image by the same amount.

The fix

<!-- the first, biggest image: no loading attribute, dimensions set -->
<img src="hero.jpg" width="1200" height="600" alt="...">

<!-- everything below the fold: lazy -->
<img src="chart.png" width="800" height="400" alt="..." loading="lazy">

Keep the width and height attributes on both, as the layout-shift guide explains, so the page does not jump when they arrive. Check your CMS and plugins: many add loading="lazy" to every image, including the first. If the image is slow because the server is slow, that is a separate problem, covered in the shared-hosting guide, since time to first byte is added to LCP whatever the front end does.

fetchpriority="high" did not help in these tests; both it and the default finished within a few milliseconds of each other. It is documented as a hint for when other requests compete with the image, which a one-image test page does not reproduce, so try it on your own page and measure rather than assuming.

Find your LCP element and see if it is lazy

Paste this into the DevTools console and reload, or run it in a snippet:

new PerformanceObserver(list => {
  const e = list.getEntries().at(-1);
  console.log('LCP', Math.round(e.startTime) + 'ms', e.element,
              'lazy:', e.element && e.element.loading === 'lazy');
}).observe({ type: 'largest-contentful-paint', buffered: true });

If it prints lazy: true, that attribute is costing you. Run it on your real templates, not just the home page, since each template can have a different LCP element. This is the same kind of check as the manual items on the pre-launch checklist, and the INP guide covers the responsiveness half of Core Web Vitals.

What this does not cover

Synthetic, Chromium only. The numbers come from a local server, a single 527 KB image, emulated throttling and five runs per cell, in headless Chromium 141. The 600ms stylesheet delay is artificial, chosen to show the mechanism, not to represent a typical site. Firefox and Safari were not tested, and the request ordering behind the inference was not traced. web.dev's larger real-world data is the better guide to the size of the effect on real sites.
After the fix. Once the image is eager, the other three parts of LCP still matter: find the slow part and fix it.

Badri Dutta

Software engineer · 8 years technical SEO

Written after a first measurement went wrong: the page's load event fired before a lazy image arrived, and the number looked excellent. The corrected test is smaller than the folklore on a bare page and much bigger when something else is slow.

Full background →