LCP phase breakdown

The LCP attribution sub-parts: TTFB, resource load delay, resource load time, element render delay.

Field data PhoneDesktopAll Scope All sites Q2 2026 edition · Phone field outcomes
Metric LCP INP CLS
1

At a glance the headline numbers for LCP phase breakdown

The LCP attribution sub-parts: TTFB, resource load delay, resource load time, element render delay.

966ms
Median LCP stack
the measures at p50
67%
Biggest: TTFB
647ms of the stack
1.5s
Headroom at p50
vs the 2.5s target

The typical LCP image waits 319ms before it even starts downloading.

The State of Web Vitals · Q2 2026 · 189,915 sites · phone field datacorewebvitals.io/state-of-cwv
2

Where the milliseconds go the phases at the median, against the budget

TTFB647ms67% of the total Load delay319ms33% of the total 2.5s target
TTFB 647ms · 67% Load delay 319ms · 33%

At the median the whole stack uses 966ms, inside the 2.5s LCP budget. The biggest piece is TTFB at 647ms, 67% of the total. computed

The State of Web Vitals · Q2 2026 · 189,915 sites · phone field datacorewebvitals.io/state-of-cwv
3

Passing LCP per phase the share of sites passing, by how long each phase takes

100% 75% 50% 25%
TTFB Load delay

Each line is one phase: left = sites where it is quick, right = sites where it drags (buckets, short to long). The steeper the fall, the more that phase decides LCP.

TTFB falls hardest: from its fastest to its slowest bucket the LCP pass rate drops 84 points, down to 10%. computed

The State of Web Vitals · Q2 2026 · 189,915 sites · phone field datacorewebvitals.io/state-of-cwv
4

The 2 distributions how each phase spreads across sites - color is the share passing in that range

TTFB p50 647ms · p75 1.2s
250–4992000+
Load delay p50 319ms · p75 549ms
100–1991000+
mostly passing tipping mostly failing

Load delay turns red in its tail - the failing sites live there. computed

The State of Web Vitals · Q2 2026 · 189,915 sites · phone field datacorewebvitals.io/state-of-cwv
5

Why this matters for the Core Web Vitals, and where to start fixing it

The LCP is a sum of four waits. TTFB is the server and the network producing the HTML. Load delay is the gap before the LCP resource even starts downloading, which is mostly a discovery problem. Load time is the download itself. Render delay is the gap between having the resource and painting it, usually render-blocking CSS or a font.

The split tells you which fix applies. A TTFB problem lives in hosting and caching. A load delay problem lives in markup and hints. A load time problem lives in image weight. A render delay problem lives in the head of the document. Optimizing the image while TTFB is the bottleneck does nothing.

How do the LCP phases affect the Core Web Vitals?

TTFB is part of the LCP itself, so this is arithmetic, not correlation. 94% of sites at the low end pass the LCP. Past 1750–1999, the typical site fails. At the top of the range only 10% pass.

Chrome field data from 189,915 sites, representing millions of real page loads. How we measured.

Live queries (6) — admin only
Query #1: 158.6 ms
SELECT COUNT(*) AS count,
            quantile_disc(m.lcp.timing.ttfb, 0.10) AS p10,
            quantile_disc(m.lcp.timing.ttfb, 0.25) AS p25,
            quantile_disc(m.lcp.timing.ttfb, 0.50) AS p50,
            quantile_disc(m.lcp.timing.ttfb, 0.75) AS p75,
            quantile_disc(m.lcp.timing.ttfb, 0.90) AS p90,
            quantile_disc(m.lcp.timing.ttfb, 0.99) AS p99
            FROM sites WHERE m.lcp.timing.ttfb IS NOT NULL;
Query #2: 181.7 ms
SELECT CASE WHEN m.lcp.timing.ttfb >= 250 AND m.lcp.timing.ttfb < 500 THEN 0 WHEN m.lcp.timing.ttfb >= 500 AND m.lcp.timing.ttfb < 750 THEN 1 WHEN m.lcp.timing.ttfb >= 750 AND m.lcp.timing.ttfb < 1000 THEN 2 WHEN m.lcp.timing.ttfb >= 1000 AND m.lcp.timing.ttfb < 1250 THEN 3 WHEN m.lcp.timing.ttfb >= 1250 AND m.lcp.timing.ttfb < 1500 THEN 4 WHEN m.lcp.timing.ttfb >= 1500 AND m.lcp.timing.ttfb < 1750 THEN 5 WHEN m.lcp.timing.ttfb >= 1750 AND m.lcp.timing.ttfb < 2000 THEN 6 WHEN m.lcp.timing.ttfb >= 2000 THEN 7 END AS bucket_idx, COUNT(*) AS n,
            quantile_disc(crux."phone".lcp, 0.5) AS median,
            COUNT(*) FILTER (WHERE crux."phone".lcp IS NOT NULL AND crux."phone".lcp <= 2500) * 1.0 / NULLIF(COUNT(*) FILTER (WHERE crux."phone".lcp IS NOT NULL), 0) AS good_pct
            FROM sites WHERE m.lcp.timing.ttfb IS NOT NULL GROUP BY bucket_idx;
Query #3: 164.0 ms
SELECT COUNT(*) AS count,
            quantile_disc(m.lcp.timing.load_delay, 0.10) AS p10,
            quantile_disc(m.lcp.timing.load_delay, 0.25) AS p25,
            quantile_disc(m.lcp.timing.load_delay, 0.50) AS p50,
            quantile_disc(m.lcp.timing.load_delay, 0.75) AS p75,
            quantile_disc(m.lcp.timing.load_delay, 0.90) AS p90,
            quantile_disc(m.lcp.timing.load_delay, 0.99) AS p99
            FROM sites WHERE m.lcp.timing.load_delay IS NOT NULL;
Query #4: 13.0 ms
SELECT CASE WHEN m.lcp.timing.load_delay >= 100 AND m.lcp.timing.load_delay < 200 THEN 0 WHEN m.lcp.timing.load_delay >= 200 AND m.lcp.timing.load_delay < 300 THEN 1 WHEN m.lcp.timing.load_delay >= 300 AND m.lcp.timing.load_delay < 400 THEN 2 WHEN m.lcp.timing.load_delay >= 400 AND m.lcp.timing.load_delay < 500 THEN 3 WHEN m.lcp.timing.load_delay >= 500 AND m.lcp.timing.load_delay < 600 THEN 4 WHEN m.lcp.timing.load_delay >= 600 AND m.lcp.timing.load_delay < 700 THEN 5 WHEN m.lcp.timing.load_delay >= 700 AND m.lcp.timing.load_delay < 800 THEN 6 WHEN m.lcp.timing.load_delay >= 800 AND m.lcp.timing.load_delay < 900 THEN 7 WHEN m.lcp.timing.load_delay >= 900 AND m.lcp.timing.load_delay < 1000 THEN 8 WHEN m.lcp.timing.load_delay >= 1000 THEN 9 END AS bucket_idx, COUNT(*) AS n,
            quantile_disc(crux."phone".lcp, 0.5) AS median,
            COUNT(*) FILTER (WHERE crux."phone".lcp IS NOT NULL AND crux."phone".lcp <= 2500) * 1.0 / NULLIF(COUNT(*) FILTER (WHERE crux."phone".lcp IS NOT NULL), 0) AS good_pct
            FROM sites WHERE m.lcp.timing.load_delay IS NOT NULL GROUP BY bucket_idx;
Query #5: 12.0 ms
SELECT COUNT(*) AS count,
            quantile_disc(m.lcp.timing.load_time, 0.10) AS p10,
            quantile_disc(m.lcp.timing.load_time, 0.25) AS p25,
            quantile_disc(m.lcp.timing.load_time, 0.50) AS p50,
            quantile_disc(m.lcp.timing.load_time, 0.75) AS p75,
            quantile_disc(m.lcp.timing.load_time, 0.90) AS p90,
            quantile_disc(m.lcp.timing.load_time, 0.99) AS p99
            FROM sites WHERE m.lcp.timing.load_time IS NOT NULL;
Query #6: 12.1 ms
SELECT COUNT(*) AS count,
            quantile_disc(m.lcp.timing.render_delay, 0.10) AS p10,
            quantile_disc(m.lcp.timing.render_delay, 0.25) AS p25,
            quantile_disc(m.lcp.timing.render_delay, 0.50) AS p50,
            quantile_disc(m.lcp.timing.render_delay, 0.75) AS p75,
            quantile_disc(m.lcp.timing.render_delay, 0.90) AS p90,
            quantile_disc(m.lcp.timing.render_delay, 0.99) AS p99
            FROM sites WHERE m.lcp.timing.render_delay IS NOT NULL;
JSON file lookups (4)
20260625/meta.json 0.05 ms
20260625/types.json 0.71 ms
20260625/loaf-scripts.json 0.33 ms
20260625/menu.json 0.11 ms