Domains, CDN & Web Delivery

Largest Contentful Paint

Definition

Only a few kinds of element can be the LCP element — an img, an image inside an svg, a video's poster frame, an element whose CSS background is loaded through url(), and any block-level element containing text. The browser picks whichever of those covers the largest area inside the viewport, ignoring anything below the fold, and re-reports as the page changes until the first user interaction. On most simple pages it is the hero image; on a page with no images it is usually the headline or the first paragraph block. Google's threshold is 2.5 seconds or less at the 75th percentile, with anything beyond 4 seconds counted as poor. The metric is part of Core Web Vitals and is measured from the start of navigation, so every delay before the page even begins is included in it.

Why It Matters

LCP is where most slow pages are actually slow, and it breaks down into four parts that can be attacked separately. Roughly speaking it is time to first byte, plus the delay before the browser starts fetching the resource, plus the download, plus the final render. On a typical failing page the resource load delay is the largest slice: the hero image is not discovered until a stylesheet has been parsed, so a 2 MB photograph does not even start downloading until 1.2 seconds in. Swapping that image for a 200 KB WebP and letting the browser find it earlier will usually do more than every other optimisation combined. The one change that reliably makes it worse is lazy-loading the hero image, which tells the browser to deprioritise the exact thing the metric is timing.

How It Works

Work through the four parts in order. Lower the first byte with caching and an edge node near the visitor. Shorten the discovery delay by referencing the hero image directly in the HTML rather than through CSS or JavaScript, adding fetchpriority=high to it, and preloading it in the head if it genuinely cannot be found early. Cut the download by exporting at the size it is displayed, choosing WebP or AVIF over PNG for photographs, and serving several widths through srcset so a phone does not fetch a desktop image. Clear the render step by keeping render-blocking CSS small, deferring non-essential scripts, and setting font-display: swap so text is not held back waiting for a web font. In a browser, PerformanceObserver with the largest-contentful-paint entry type reports the element and timestamp directly, which is the fastest way to find out what the page thinks its LCP element is.

Real-World Example

A photographer publishes a portfolio on 99helpers at maren-studio.99helpers.site. The LCP element is a full-width 3,600 pixel JPEG weighing 2.8 MB, and mobile LCP sits at 4.6 seconds. Re-exporting it at 1,600 pixels as a 210 KB WebP, referencing it as a plain img tag with fetchpriority=high instead of a CSS background, and removing its loading=lazy attribute brings LCP to 1.4 seconds. The page looks identical on screen.

Common Mistakes

  • Adding loading=lazy to the hero image — the browser then delays the one download the metric is waiting on
  • Setting the LCP image as a CSS background, so it is not discoverable until the stylesheet has been fetched and parsed
  • Preloading half a dozen resources at once, which spreads bandwidth thinly and delays the image that actually matters
  • Assuming a fast server settles it — a 100 ms first byte still ends in a 4 second LCP if a 3 MB image sits behind it

Related Terms

Put a file online in seconds

Drop in a document, an image, a page or a whole static website and share the link — free, with no build step and no server to set up.

Host a file free →