Two pages both report a Largest Contentful Paint (LCP) of about 4 seconds. On the first, the phase breakdown is dominated by resource load delay; on the second, by element render delay. What is likely wrong with each, and how does the remedy differ?
answer
- dead time before, versus blocked after
- one is discovery, one is unblocking
- check the raw HTML, not the DOM
- both fail; neither is a compression problem
- background images and injected heroes hide from the scanner
basics
~20 sDominant load delay means the browser found out about the LCP resource too late — it was not in the initial HTML, or was deprioritised. Dominant render delay means the bytes arrived but painting was blocked, by render-blocking resources, a busy main thread, or content that only exists after client-side rendering.
solid answer
~50 sThey are opposite failures. **Load delay** is dead time before the fetch even begins, so the resource was undiscoverable when the document arrived: it is a CSS `background-image` the browser only learns about after the stylesheet parses, it is injected by script after hydration, it sits in a carousel or behind a lazy-loading attribute, or it was queued behind higher-priority downloads. The fix is discovery — get a real reference to it into the initial HTML response so the preload scanner sees it immediately, and make sure nothing is deferring or deprioritising it. **Render delay** means the pixels were ready and something stopped them appearing: render-blocking stylesheets or scripts, a long main-thread task, the hero markup only existing after client-side rendering, or text waiting on a webfont. The fix is unblocking — cut render-blocking work on the critical path, break up long tasks, and get the element into the server's HTML so it can paint without JavaScript. Compressing the image helps neither case; that only moves load duration.
go deeper
Know that a slow LCP has more than one possible cause, and that the browser must first find the resource, then download it, then be free to paint it.
Explain what makes a resource undiscoverable to the preload scanner — CSS background images, script-injected markup, deferred loading — and name the main things that block a paint once bytes are in hand.
Show the diagnosis path end to end: read the phases, confirm against the raw HTML response and the gap between resource completion and paint, and pick the remedy the data supports rather than the habitual one.
Frame the two cases by cost and ownership — discovery fixes are cheap template changes, render-delay fixes usually mean renegotiating the JavaScript and third-party budget — and set the expectation that LCP regressions arrive with phase data attached.
## Same number, opposite diseases The reason the phase breakdown is worth computing is exactly this scenario. Both pages are 4 seconds, both will fail the same dashboard check, and the work required is completely different. Neither is fixed by the reflex answer of making the image smaller — in both, load duration is a minority of the total. ## Page one: load delay dominates Load delay is the interval between the document's first byte and the browser *starting* to fetch the LCP resource. Nothing productive happens in it. A large value means the browser did not know it needed that resource, or knew and chose to fetch other things first. The usual causes, roughly in order of how often they turn up: - **The image is a CSS `background-image`.** The browser cannot know about it until the stylesheet has downloaded and been parsed and the element has been matched and laid out. The preload scanner — which races ahead of the parser grabbing URLs out of the raw HTML — cannot see inside CSS. This alone can add hundreds of milliseconds. - **The image is injected by JavaScript.** A hero rendered client-side does not exist as markup in the response, so the fetch cannot begin until the script has downloaded, parsed, executed and rendered. Load delay then contains an entire JavaScript pipeline. - **It is deferred by the page's own loading strategy.** An above-the-fold image marked for lazy loading, or one that lives on a carousel slide that is not the first, has its fetch deliberately postponed — a defensible choice for content below the fold, a self-inflicted wound for the LCP element. - **It is queued behind other work.** Images are fetched at a lower priority than blocking scripts and stylesheets by default, so a heavy critical path can leave the hero waiting in line while it is technically "discovered". The common thread is *discoverability*, and so is the remedy: put a real, statically-visible reference to the LCP resource in the HTML the server sends, so the preload scanner starts the fetch in the first milliseconds; do not defer the one image the metric is about; and make sure it is not competing with work that could have waited. A useful confirmation step before you change anything: view the raw HTML response, not the inspected DOM. If the LCP element's URL does not appear in the bytes the server sent, load delay is guaranteed to be large and you have already found the cause. ## Page two: render delay dominates Render delay runs from the resource being available to the element actually painting. A large value means everything the element needed was in hand and it still did not appear. Causes: - **Render-blocking resources.** The browser will not paint until it has the CSSOM. A stylesheet still downloading — or worse, one that pulls in another with `@import` — holds first paint hostage no matter how ready the image is. - **A busy main thread.** Painting is main-thread work. If a long task is executing — a big hydration pass, a heavy third-party script, an expensive synchronous parse — the frame simply cannot be produced until it yields. - **Client-side rendering.** If the element only exists once a framework has rendered it, the wait for that render lands squarely in render delay. - **Font blocking text.** For a text LCP, the text may be laid out but invisible while a webfont loads, depending on the font-display behaviour in play. The paint is deliberately withheld. The remedy is *unblocking*: shrink the render-blocking critical path, move non-essential script off the initial load, break long tasks so the browser can paint between them, and — the highest-leverage move for a client-rendered hero — have the server emit the element in the HTML so it can paint before any JavaScript runs. ## Telling them apart when the data is thin If you only have the total LCP and no phase split, two cheap checks separate the cases. First, search the raw HTML response for the LCP element's URL: absent means load delay. Second, compare the moment the resource finished loading with the LCP timestamp: a wide gap between them means render delay. Both are answerable from a single trace, and both are more reliable than intuition, because the intuition of nearly every team is "the image is too big" — which is a *third* phase entirely and, in these two pages, not the problem at all. ## Why the distinction is worth arguing for The two remedies cost different things and land on different teams. Fixing discovery is usually a small, cheap markup or templating change with a large effect. Fixing render delay often means renegotiating the JavaScript budget or the third-party inventory, which is an organisational conversation rather than a patch. Naming which one you are in — with the phase numbers to back it — is what turns "the page is slow" into a piece of work someone can actually own.
- Where does a slow TTFB show up in this picture, and what does it do to the other phases?TTFB is the first phase, and every later phase begins after it, so a slow document response shifts the whole timeline right by that amount. It does not enlarge load delay or render delay, but it eats the budget they have to fit into — which is why you fix the document response before spending effort on the page.
- How do you tell whether render delay comes from blocking resources or from client-side rendering?Check whether the element exists in the HTML the server sent. If it does, the markup was ready and something blocked the paint — look at render-blocking CSS and long tasks on the main thread. If it does not, the wait is the JavaScript pipeline itself, and no amount of unblocking CSS will help until the element is server-rendered.
- Could a page show large values in both phases at once?Yes, and it is common on heavily client-rendered pages: the script pipeline delays the fetch of the hero, then the same busy main thread delays the paint once it arrives. The single fix — emitting the hero in the server's HTML — addresses both, which is why phase data so often points at one change rather than two.
saying these in an interview costs you the question
- Prescribes a CDN for every slow LCP regardless of phase
- Says compress the hero image without checking which phase dominates
- Treats a large render delay as evidence the image file is too big
- Recommends lazy-loading the hero image to save bandwidth
- Inspects the DOM rather than the raw HTML response when checking discoverability