Skip to main content
Server & DevOpsSeptember 29, 20266 min read

Your Images Are Probably Not What Makes LCP Slow

Get technical support

We measure your store before touching it

Cloudflare's BEACON data from 10,000 large sites shows where slow LCP comes from. On pages rated poor, downloading the LCP resource took 119 ms, while the first byte, late discovery and blocked rendering each took one and a half to two seconds.

What BEACON Is

On September 28, 2026, Cloudflare published BEACON, an anonymized dataset of real-user performance measurements from 10,000 of the largest websites on its network. It covers every major browser engine, is updated daily in Google BigQuery, and follows the format of the community RUM Archive. Domains and URL paths are stripped, and groups with fewer than five data points are dropped, so no single site can be picked out.

It reports the Core Web Vitals as full histograms, and it splits Largest Contentful Paint into its four parts. That split answers a question most speed audits skip, which is where the time actually goes.

The Four Parts of LCP

  • Time to first byte. Nothing can render until the HTML arrives.
  • Load delay. The time between the first byte and the moment the browser starts fetching the LCP resource.
  • Load duration. How long that resource, usually an image, takes to download.
  • Render delay. The time between the resource arriving and the element appearing on screen.

web.dev suggests a healthy page spends about 40 percent of its LCP on the first byte and about 40 percent on the download. The two delays should stay under 10 percent each, and web.dev's advice is to get them as close to zero as possible.

What the Data Shows

Cloudflare grouped page views by their LCP rating and reported each part:

LCP ratingFirst byteLoad delayDownloadRender delay
Good598 ms76 ms119 ms157 ms
Needs improvement1,015 ms1,049 ms199 ms437 ms
Poor1,891 ms1,485 ms119 ms2,002 ms

The download column barely moves. It stays between 119 and 199 ms in every group, while the other three grow between three and twenty times from good pages to poor ones. Cloudflare's own reading is that downloading the resource typically contributes the least, and that most slow pages would gain more from having the LCP resource discovered sooner and from removing whatever blocks its render.

One caution applies. These are the largest sites on Cloudflare, and many of them already serve images through a CDN in modern formats. A small store sending a three-megabyte hero photo can still lose real time in the download, and for that store the image file does matter. For most slow pages, though, the bigger wins sit in the other three columns.

Slow First Byte

On a Magento or WordPress store, a slow first byte usually means the server builds every page on every request. A full-page cache fixes that for anonymous visitors. On Magento that means Varnish in front of the application, and on WordPress a page cache plugin or a cache at the web server, with the HTML cached at the CDN where the pages allow it. Redirect chains add to the first byte as well, so a visitor who lands through two redirects starts late before any content exists. The Magento 2 speed levers that actually move LCP covers the server side in detail.

Late Discovery

Load delay grows when the browser cannot see the LCP resource early. The usual causes:

  • The LCP image is lazy-loaded, often by a plugin that applies loading="lazy" to every image on the page.
  • The image is a CSS background, which the browser only finds after the stylesheet has loaded.
  • The image is inserted by JavaScript, for example by a slider or a client-rendered component.

The fix is to put the LCP image in the HTML as a plain <img>, never lazy-load it, and mark it as the priority:

<img src="/media/hero.webp" width="1200" height="675" fetchpriority="high" alt="Autumn collection">

For a background image that has to stay in CSS, preload it from the head with fetchpriority="high". Our image pipeline guide goes through these rules one by one.

Blocked Rendering

In Cloudflare's table, the render delay of poor pages is the largest single part, at 2,002 ms. web.dev lists what causes it:

  • stylesheets and synchronous scripts in the head that block rendering
  • the LCP element not being in the page yet, because JavaScript still has to add it
  • an A/B testing tool hiding the page while it decides which variant to show
  • long tasks keeping the main thread busy

Inline the CSS the top of the page needs, defer the rest along with the scripts, and look hard at anti-flicker snippets, which hide the page on purpose until the testing tool has loaded.

Responsiveness Follows the Same Pattern

BEACON splits Interaction to Next Paint into input delay, processing time and presentation delay. For interactions rated poor, the three came to 84, 284 and 217 ms. Cloudflare notes that JavaScript execution takes the longest in the slowest interactions, and that presentation time rises sharply as well, usually because of complex CSS layout recalculation. Heavy themes and third-party scripts show up on both sides.

Single-Page Apps Pay on the First Load

Navigations inside a single-page app were two to three times faster than full page loads at every percentile, 582 ms against 1,421 ms at the 75th percentile. Landing pages were a different story, with an LCP of 2,681 ms at the same percentile, because the first load is often considerably heavier. Cloudflare's advice is to weigh the two, since a visitor who never goes past the landing page only ever gets the slow part.

Measure Your Own Split

You do not need BEACON to see your own numbers. The Performance panel in Chrome DevTools breaks LCP into these parts in its insights, and for real visitors the attribution build of the web-vitals library reports all four:

import { onLCP } from 'web-vitals/attribution';

onLCP(({ value, attribution }) => {
  navigator.sendBeacon('/your-rum-endpoint', JSON.stringify({
    lcp: value,
    timeToFirstByte: attribution.timeToFirstByte,
    resourceLoadDelay: attribution.resourceLoadDelay,
    resourceLoadDuration: attribution.resourceLoadDuration,
    elementRenderDelay: attribution.elementRenderDelay,
  }));
});

Compare your split with the Good row above. If the download is your largest part, the image is worth optimizing. If one of the other three is, a smaller image will not change much. Cloudflare says it will add the same breakdown to its Real User Monitoring dashboard in the coming weeks, and the queries behind its post are in BigQuery for anyone who wants to slice the data differently.

Finding which part is slow on a real store, and fixing it, is where Magento 2 Speed Optimization and WordPress Speed Optimization start.

Sources

Or read how we handle it in Magento 2 Speed Optimization.