LCP Subpart Breakdown Analyzer
Decompose Largest Contentful Paint into Chrome's four official subparts, verify that they actually add up, compare every phase against the published 40 / 10 / 40 / 10 budget, and get the exact milliseconds each phase must shed to reach your target. Runs entirely in your browser.
1. Scenario — load a realistic profile or enter your own numbers below
Every preset is internally consistent: the four subparts sum exactly to the stated LCP, which is the invariant the browser guarantees.
2. Input mode
A text LCP element has no resource to fetch, so load delay and load duration are structurally zero and the budget is renormalised over the two phases that remain.
3. Measurements — milliseconds, from the web-vitals attribution build or the DevTools LCP insight
Leave measured LCP at 0 in the first mode to skip the cross-check. The 2500 ms default target is Google's Core Web Vitals "good" threshold at the 75th percentile.
4. Identity check — TTFB + load delay + load duration + render delay = LCP
5. Result
6. Proportional timeline — actual against the ideal allocation, both drawn to the same scale
All three bars share one horizontal scale, set by the larger of your actual LCP and the target, so a shorter bar genuinely means a faster page rather than a rescaled drawing.
7. Per-phase audit
| Phase | Actual | Share | Ideal share | Ideal at this LCP | Overspend | Overspend (pp) | Budget at target | Must shed |
|---|
8. Diagnosis and remediation — ordered by the milliseconds each phase must give back
The method, exactly
Largest Contentful Paint is not a single measurement, it is the end of a chain. Chrome exposes that chain as four consecutive intervals, documented in web.dev's Optimize LCP guide and surfaced programmatically by the attribution build of Google's web-vitals library. The intervals are mutually exclusive and collectively exhaustive, which gives the one hard invariant this page is built around.
What each subpart actually measures
- Time to first byte. Navigation start to the first byte of the main document response. Contains DNS, connection, TLS, redirects, and server think time.
- Resource load delay. First byte of the document to the instant the browser starts fetching the LCP resource. This is pure waiting. It is the discoverability metric.
- Resource load duration. Start to end of the LCP resource fetch. This is the only phase where bytes on the wire are the real cost.
- Element render delay. End of that fetch to the frame in which the element is painted. Render-blocking CSS and JavaScript, font swaps, decode cost and hydration all land here.
For a text LCP element there is no resource, so the middle two intervals are zero by construction and LCP collapses to time to first byte plus element render delay.
The budget this page audits against
web.dev's guidance gives a target distribution rather than absolute per-phase limits, because what is affordable in each phase depends on the total. The recommended allocation is:
The logic behind the shape is that the two 40 percent phases are unavoidable work — a server must respond and bytes must travel — while the two 10 percent phases are overhead. A page spending 45 percent of its LCP in load delay is not slow because of bandwidth; it is slow because the browser did not know what to fetch.
Applied to the 2500 ms "good" threshold this yields a 1000 ms time-to-first-byte allowance. Note that the standalone TTFB recommendation is stricter at 800 ms or less, so the page flags a TTFB above 800 ms even when its percentage share looks acceptable.
How overspend is computed
Two different comparisons are reported, because they answer different questions.
The first block is scale-free: it tells you whether the shape of the load is right, even on a page that is already fast. The second block is absolute: it tells you what each phase is allowed to cost if the page is to hit the target at all.
Distributing the required saving
The total saving needed is simply max(0, LCP - target). That saving is allocated across phases in proportion to how far each one exceeds its own target budget:
This allocation has a useful property. Because the budgets sum exactly to the target, the sum of the positive excesses is always at least the needed saving, so every shed_i is bounded by excess_i. No phase is ever asked to go below its own budget, and phases already inside budget are never asked for anything. A phase that is under budget acts as slack: if time to first byte is already lean, the analyzer will not pretend the fix has to come from the server.
Validation, not silent acceptance
Real measurements get transcribed wrong, mixed across sessions, or pulled from different percentiles. The identity is checked explicitly and the signed residual is reported:
- residual near zero — consistent, within the tolerance you set.
- residual positive — the subparts do not reach the stated LCP; time is unaccounted for, usually because the values came from different page loads or a percentile was mixed with an average.
- residual negative — the subparts overshoot the stated LCP. This is impossible in a single real observation, since the intervals do not overlap.
In solve mode the missing subpart is recovered by subtraction, and a negative result is reported as an error rather than clamped away.
The late-discovery signature
When resource load delay exceeds 25 percent of total LCP — two and a half times its recommended ceiling — the cause is almost never the network. It is one of a small, well-known set of discoverability failures:
- The LCP image is a CSS
background-image, so it cannot be found until the stylesheet has downloaded and the rule has matched. - The image is injected by JavaScript, or lives behind a client-side route or carousel, so it does not exist until a bundle has executed.
- The
imgtag carriesloading="lazy", which defers the one image that must never be deferred. - The request is queued behind render-blocking stylesheets and scripts, or was assigned a low initial priority.
- The image arrives via a redirect chain or a different origin that still needs connection setup.
Reading the real numbers off your own page
The attribution build of web-vitals returns all four values directly. Chrome DevTools shows the same split in the Performance panel's LCP insight.
In web-vitals v3 the third field was named resourceLoadTime; it became resourceLoadDuration in v4. Field data from the Chrome UX Report does not include this split, so the subparts always come from your own lab or RUM instrumentation.
Thresholds used on this page
- Good — LCP at or below 2500 ms
- Needs improvement — above 2500 ms, at or below 4000 ms
- Poor — above 4000 ms
- Time to first byte: good at or below 800 ms, poor above 1800 ms
All Core Web Vitals thresholds are evaluated at the 75th percentile of page loads, segmented separately for mobile and desktop. Feeding this tool a median or an average will produce a diagnosis of a page load that nobody actually experienced.
Frequently asked questions
fetchpriority="high" on a normal img tag before reaching for a preload.Last updated 29 July 2026