What LCP measures
LCP is a Core Web Vital. It is the time, from navigation start, until the largest visible element on the page finishes rendering. The “largest” is measured by pixel area inside the viewport at the moment of paint.
The browser tracks LCP automatically as it renders the page. It keeps a running candidate, updating whenever a larger element paints. The final LCP value reported is the last candidate before the user starts interacting with the page. Any tap, scroll, or key press halts the measurement.
LCP correlates with the subjective experience of “the page loaded”. The hero image is in. The headline is visible. The video poster is up. The user can start reading or clicking.
What counts as an LCP element
The browser considers a constrained set of element types as LCP candidates:
<img>and<image>(inside SVG)<video>poster frames- Elements with a
background-imageset via CSS - Block-level elements containing text nodes
Inline SVGs, decorative pseudo-elements, and elements hidden by opacity: 0 or fully clipped by clip-path are excluded. The candidate must intersect the viewport and have a final paint size; partially-loaded images do not count until the load completes.
This matters because the LCP element is rarely the one you would guess. A 1200x600 hero image is the usual suspect, but on a content-heavy page with no hero, the LCP might be a paragraph of text. On a product page, it might be the product image. On a video player, it might be the poster frame. Always check before optimising.
The field vs lab gap
Two different worlds measure LCP, and they disagree more often than teams expect.
Field data comes from real users via the Chrome User Experience Report (CrUX) or your own Real User Monitoring. It is what your customers actually experience: their networks, their CPUs, their cached or uncached visits, every browser tab they have open. CrUX reports the 75th percentile over a 28-day window. RUM gives you per-session data.
Lab data comes from synthetic measurement. PageSpeed Insights, Lighthouse, WebPageTest, and real-browser load testing platforms all run controlled tests against a target URL. The environment is fixed: known network throttling, known CPU profile, known viewport. Results are reproducible.
The gap appears because lab tests run one browser at a time, on a fast network, with no competing tab activity, and usually against a server with no concurrent load. Real users hit a server already serving thousands of others, on flaky mobile networks, with eight tabs open. Their LCP is worse.
This is where real-browser load testing earns its place. Run a 1,000-virtual-user test against your production-shaped server. Now every virtual user is a real browser firing real requests at a server under real contention. The LCP that comes back is calibrated to peak load, not to ideal conditions.
What pushes LCP up
The usual culprits, ranked by how often we see them on demo calls:
- Slow server response (TTFB). The LCP HTML chunk has not arrived yet. Everything else is moot. Real-browser load tests expose this because TTFB visibly worsens as concurrency rises.
- Render-blocking resources. CSS in
<head>with nomediaattribute, synchronous JavaScript, web fonts. The browser cannot paint until these resolve. - The LCP image is not preloaded. The image discovery happens late in the render path, so the request fires after layout. A
<link rel="preload">for the LCP image cuts hundreds of milliseconds. - CDN cache misses on the LCP asset. If the LCP image is uncached at the edge for first-time visitors, you will see LCP spikes on the cold-cache portion of your traffic.
- Third-party tags blocking the main thread. Analytics, A/B testing, consent banners. They delay paint by occupying the JavaScript engine when it should be rendering.
- Layout thrashing during render. Web fonts that swap mid-paint trigger reflow. Late-arriving stylesheets recompute the entire DOM. Both reset the LCP candidate.
How to test LCP honestly
Treat lab and field as complementary. RUM tells you what is happening. Lab tells you what would happen if you changed something.
For lab measurement at scale, real-browser load testing is the right tool. Every virtual user is a real Chromium instance with its own memory, cache, and network stack. The LCP capture is native to the browser, not a heuristic. The numbers match what your customers’ browsers would record under the load you are testing.
If you also need per-page Vitals budgets enforced in CI, the same scenarios run as post-deploy smoke checks (the Testing Suite roadmap covers this). The build fails when LCP busts the budget on a critical page.
Common mistakes
- Measuring LCP without load. A 1.8s LCP on Lighthouse means little if your peak-traffic LCP is 5.2s.
- Optimising the wrong element. Verify the LCP candidate before swapping the hero image format. The LCP might be a paragraph.
- Reporting the mean. The 75th percentile is the published threshold. The 99th percentile is the customer support backlog.
- Treating LCP as a one-off. Web Vitals drift. A third-party tag added six weeks ago might have pushed LCP up 400ms with no other code change.
LCP is one of three Core Web Vitals. The companion metric for responsiveness is Interaction to Next Paint, which replaced First Input Delay in March 2024.