Core Web Vitals

Late LCP Discovery: Why Critical Resources Start Loading Too Late

September 15, 2026 webperflab_admin 15 min read

Core Web Vitals

An LCP resource can be perfectly optimized and still start loading too late. If the browser does not discover that resource until after CSS, JavaScript, hydration, an API response or another dependency completes, the request begins late regardless of file size.

That makes late LCP discovery a timing and dependency problem before it is an image problem.

The first question should not be “Should I preload the hero?” It should be: What prevented the browser from knowing about this resource earlier?

What causes late LCP discovery?

Late LCP discovery happens when the browser does not learn about the LCP resource early in the loading process. Common causes include CSS background images, JavaScript-generated markup, client-side rendering, API dependencies and lazy-loading logic. Diagnosis requires checking the resource start time, request initiator and dependency chain rather than looking only at image size.

What Is Late LCP Discovery?

Browsers cannot request a resource they do not yet know exists.

Late discovery occurs when a critical resource becomes known only after one or more earlier steps have completed.

VISUAL 1 — Early vs Late LCP Discovery

Early: HTML → LCP image
Late: HTML → JavaScript → component → LCP image

Possible causes include:

  • the resource is absent from the initial HTML;
  • it is referenced only inside CSS;
  • JavaScript creates the element later;
  • an API response is required before the component can render;
  • framework hydration or client-side rendering must complete first;
  • a slider or page builder initializes the hero dynamically;
  • lazy-loading logic delays the request;
  • the resource sits several steps away from the document in a dependency chain.

Late discovery is contextual. There is no universal “after X milliseconds = late” rule. The key evidence is that the document or earlier dependencies are already available while a user-critical resource begins materially later because the browser did not know about it sooner.

Discovery Delay Is Different From Download and Render Delay

VISUAL 2 — Discovery vs Download vs Render

Document → Discovery → Request Start → Resource Complete → Render → LCP

DISCOVERY DELAY

Browser does not know the resource yet

The request cannot begin because an earlier dependency must reveal the resource.

LOAD DURATION

Browser knows the resource but transfer is slow

The request has started, but receiving the response takes too long.

RENDER DELAY

Resource is available but paint is late

The browser has the resource, but CSS, JavaScript, rendering or application state delays presentation.

This article owns the first category: discovery.

For the broader routing model, see the LCP root-cause framework. If the resource loads early and quickly but LCP remains late, see LCP image loads fast but LCP is still slow.

First Confirm the Actual LCP Element

Do not begin late-discovery diagnosis by assuming the visually largest hero image is the LCP element.

First confirm the element the browser is actually reporting.

The LCP candidate can be:

  • an image;
  • a text block;
  • a qualifying CSS background image;
  • a video poster;
  • another eligible visible element.

The candidate can also change during page load.

Diagnosis starts from the measured LCP candidate, not the design assumption.

See identify the LCP element.

Find the LCP Resource in the Network Waterfall

Once the LCP element is confirmed, identify the exact network resource associated with it.

Then:

  1. find the request in the Network panel;
  2. compare its start time with the document timeline;
  3. check when the document became available;
  4. inspect the request initiator;
  5. trace the dependency that exposed the resource.

If the element uses a responsive image, inspect the resource the browser actually requested—not just the URL visible in a CMS or editor.

src is not always the final downloaded resource. Browser selection can involve srcset, sizes, viewport conditions and device characteristics.

For the full waterfall methodology, see the network waterfall guide.

When Did the Browser Learn About the Resource?

This is the central question.

At what point in the loading path did the browser first have enough information to request the resource?

Compare:

  • document response timing;
  • resource request start;
  • initiator;
  • the requests or application work immediately preceding it.

If the document is already available but the critical resource starts materially later, there is a discovery gap to investigate.

The size of that gap alone does not prove the cause. The dependency path does.

How HTML-Based Discovery Works

A critical resource exposed directly in initial HTML can often be discovered earlier than a resource that only becomes visible after another dependency completes.

VISUAL 3 — HTML vs CSS vs JavaScript Discovery Paths

HTML path: HTML → image
CSS path: HTML → CSS → background image
JS path: HTML → JavaScript → component → image

This does not mean:

  • every hero image must always be hard-coded in HTML;
  • every HTML-discovered resource automatically receives the highest priority;
  • every non-HTML resource is a performance problem.

The point is simpler: fewer required steps before discovery can allow a critical request to begin earlier.

CSS Background Images and Late Discovery

A background image referenced through CSS can introduce an additional discovery dependency.

A simplified path may look like:

HTML→
CSS discovery→
CSS download / processing→
background image discovery

That can delay request start compared with a resource that is already exposed to the browser earlier in the document path.

CSS background images are not inherently bad for LCP. The performance question is whether the implementation creates a meaningful discovery delay for the actual LCP resource.

If the waterfall shows a CSS-initiated LCP resource beginning late, inspect the stylesheet dependency and whether the critical resource can be safely exposed earlier.

JavaScript-Generated LCP Resources

If JavaScript creates the LCP element, discovery can depend on both network and CPU work.

A simplified path may be:

HTML→
JS download→
JS execution→
DOM update→
LCP image request

Examples include:

  • client-rendered heroes;
  • JavaScript-created images;
  • components mounted after startup;
  • sliders initialized after page scripts execute;
  • page-builder modules that inject the visible asset later.

This does not mean all JavaScript-rendered content is inherently slow.

The question is whether JavaScript is a required dependency before the browser can know the critical resource exists.

API and Data Dependencies Can Delay LCP Discovery

Some critical UI cannot render until data arrives.

HTML→
JavaScript→
API request→
API response→
component render→
LCP resource

In this pattern, compressing the image does not remove the upstream dependency.

The investigation should ask:

  • Does the hero truly need that data before its critical resource can be known?
  • Can a critical shell or resource reference exist earlier?
  • Can the dependency chain be shortened without changing required functionality?

This is an architecture question, not an image-format question.

Hydration and Client-Side Rendering

A framework-based page may have visible critical content that is not fully available until:

  • hydration;
  • client-side routing;
  • component initialization;
  • application state setup;
  • runtime rendering.

If the LCP resource only becomes known after these steps, the request can start late even if the file itself is small.

Do not assume hydration is automatically the problem. Confirm the resource’s initiator and the timing relationship first.

Lazy Loading Can Delay a Critical Resource

Lazy loading is useful for resources that do not need to load immediately.

But a critical above-the-fold LCP resource can be delayed if its loading strategy waits for:

  • native lazy-loading heuristics;
  • a JavaScript lazy-loader;
  • Intersection Observer logic;
  • a component becoming visible;
  • another application event.

Native lazy loading and JavaScript lazy loading are not identical mechanisms, but both can affect request timing depending on implementation.

Do not disable lazy loading globally. If evidence shows the actual LCP resource is being delayed, adjust the loading behavior of that critical resource rather than removing lazy loading from unrelated content.

Sliders, Page Builders and Dynamic Hero Content

Hero sliders and CMS/page-builder output deserve investigation because the critical resource can be represented in very different ways:

  • directly in HTML;
  • inside inline CSS;
  • inside an external stylesheet;
  • as a data attribute;
  • inside JavaScript configuration;
  • inserted only after slider initialization.

A visual editor does not reveal the browser’s actual discovery path.

Inspect generated output and runtime behavior, not the CMS editor interface.

A slider is not automatically an LCP problem. Confirm whether it actually creates a late critical request.

Use the Request Initiator to Trace the Dependency

The request initiator helps answer:

What caused this request to start?

Depending on the request, the initiator may point toward:

  • the parser;
  • a stylesheet;
  • a script;
  • a JavaScript call path;
  • another resource or browser activity.

For late discovery, initiator evidence is especially valuable because it connects the late start time to the mechanism that exposed the resource.

Example:

Observation: LCP image starts late.
Initiator: JavaScript component.
Dependency: component does not mount until API data resolves.
Hypothesis: API-driven rendering delays LCP resource discovery.

That is much stronger than simply saying “the LCP image loads late.”

How Dependency Chains Push Critical Requests Later

A critical resource may sit several steps away from the document.

CSS path

HTML → stylesheet → background image

JavaScript path

HTML → JavaScript → component → image

Data-driven path

HTML → JavaScript → API → component → image

Lazy path

HTML → lazy logic → visibility condition → image

Each required step creates another opportunity for the critical request to start later.

The engineering goal is not “remove every dependency.”

It is to ask whether the user-critical resource needs to be that far from the document and whether the discovery chain can be shortened safely.

Preload: When It Can Help

Preload can help when a genuinely critical resource is known to the application but normal browser discovery occurs too late.

It can allow the browser to begin fetching the resource earlier than it otherwise would.

Preload is most defensible when:

  • the resource is confirmed as user-critical;
  • the actual candidate is known;
  • normal discovery is measurably late;
  • the preload matches the resource the page will really use;
  • it does not create duplicate or unnecessary transfer.

It may provide little benefit when:

  • the resource is already discovered early;
  • render delay is the real bottleneck;
  • the wrong responsive candidate is preloaded;
  • several hero variants are preloaded unnecessarily;
  • the resource is not actually the final LCP candidate.

For the implementation decision, see preload the LCP image.

Preload vs fetchpriority

These mechanisms address different parts of the loading problem.

Technique Primary role What it does not replace
Preload Can expose and request a known critical resource earlier Root-cause diagnosis, server response improvement, render-delay fixes
fetchpriority Provides a fetch-priority hint for a resource the browser knows about Resource discovery itself

Discovery first. Priority second.

A resource discovered at 2 seconds can still be too late even if it receives high priority immediately after discovery.

Likewise, a resource can be discovered early but still be scheduled at a lower priority than desired.

These are related but separate problems.

Why High Priority Cannot Fix a Resource the Browser Does Not Know About

Priority hints influence scheduling after the browser has enough information to identify the resource.

If the image does not exist from the browser’s perspective until JavaScript creates it, assigning high priority does not erase the earlier dependency chain.

A high-priority request that begins late is still a late request.

This is why late-discovery diagnosis must happen before priority tuning.

Early Hints and Other Earlier-Exposure Strategies

Some architectures can expose critical resources before the final HTML response through mechanisms such as Early Hints or server-generated resource hints.

These approaches can be useful in specific systems, but they should not be treated as default fixes for every LCP problem.

The same diagnostic rule applies: first prove that discovery timing is a meaningful bottleneck.

Third-Party Injection Can Create Late LCP Discovery

A third-party script can inject:

  • images;
  • widgets;
  • banners;
  • embedded content.

If one of those elements becomes the LCP candidate, its request may depend on the third-party script’s own network and execution path.

Confirm the initiator before attributing the delay to third-party code.

A Practical Late-Discovery Diagnostic Workflow

Identify the actual LCP element

Confirm the browser-reported candidate.

Identify the exact requested resource

Verify the actual image candidate or asset in the Network panel.

Find the request in the waterfall

Locate its request start and completion timing.

Compare request start with document timing

Look for a meaningful discovery gap.

Inspect the Initiator

Determine what caused the browser to request the resource.

Trace the dependency chain

Identify CSS, JavaScript, API, hydration or lazy-loading steps before discovery.

Determine why the resource was not known earlier

Separate architecture from scheduling and transfer issues.

Form a root-cause hypothesis

State which dependency creates the late discovery and what evidence supports it.

Choose the smallest appropriate change

Expose the resource earlier only as much as the evidence justifies.

Verify earlier discovery and LCP impact

Re-check waterfall, candidate selection and LCP timing after the change.

Discovery Pattern → Evidence → Likely Cause → Next Investigation

Discovery pattern Evidence Likely cause Next investigation
Image request begins after JavaScript execution Waterfall + Initiator JavaScript-based discovery Inspect script or component dependency
Background image begins after stylesheet processing Initiator + CSS timing Stylesheet dependency Inspect critical CSS / resource exposure path
Resource begins after API response Waterfall + initiator/dependency chain Data-driven rendering Inspect whether critical resource can be known before data completion
Resource begins after lazy-loading logic Initiator + runtime timing Lazy-loading dependency Adjust handling of the confirmed critical resource
Resource begins after slider or page-builder initialization Generated markup + waterfall + initiator Dynamic component discovery Inspect whether critical asset can be exposed earlier

Technique → What It Can Help → What It Cannot Fix

Technique What it can help What it cannot fix
Preload Late resource discovery when the correct critical resource is known Server TTFB, JavaScript render delay, incorrect LCP candidate
fetchpriority Scheduling / priority hint after resource discovery A resource unknown to the browser
Image compression Resource transfer duration Discovery timing
CDN Delivery and transfer under appropriate conditions JavaScript or API dependency chains
Markup exposure Can shorten discovery path when architecture permits Slow transfer or late rendering by itself

A Late LCP Discovery Decision Tree

VISUAL 4 — Late Discovery Decision Tree

Late start → Initiator → Dependency → Earlier exposure decision → Verification

DOES THE LCP RESOURCE START LATE?
│
├─ NO
│  └─ Late discovery is probably not the main issue
│
└─ YES
   ↓
WHAT INITIATED THE REQUEST?
│
├─ HTML PARSER
│  └─ Check scheduling → priority → loading conditions
│
├─ CSS
│  └─ Inspect stylesheet dependency
│
├─ JAVASCRIPT
│  └─ Inspect execution → component dependency
│
├─ API-DRIVEN RENDER
│  └─ Inspect data dependency
│
└─ LAZY-LOAD MECHANISM
   └─ Inspect loading logic
        ↓
CAN THE RESOURCE BE SAFELY EXPOSED EARLIER?
│
├─ YES
│  └─ Consider markup → preload → loading strategy as appropriate
│
└─ NO
   └─ Reduce dependency or redesign the critical path

Common Late-Discovery Diagnosis Mistakes

Preloading immediately because LCP is slow

First prove the actual resource starts late because of discovery.

Not confirming the actual LCP element

The assumed hero may not be the measured candidate.

Not checking the actual image candidate

Responsive selection may produce a different request than the CMS URL.

Looking only at file size

Transfer size does not explain late request start.

Ignoring request start time

Discovery timing is the core evidence.

Ignoring the Initiator

Without it, the dependency that exposed the resource may remain unknown.

Confusing late discovery with slow download

One delays request start; the other extends transfer after start.

Confusing late discovery with render delay

A resource can load early but still paint late.

Using fetchpriority as a discovery fix

Priority does not reveal a resource the browser has not discovered.

Disabling lazy loading site-wide

Target the confirmed critical resource instead.

Preloading multiple hero variants

Unnecessary variants can compete for bandwidth.

Preloading the wrong responsive candidate

The browser may still request another image.

Creating duplicate fetches

A mismatched preload can add work rather than remove delay.

Not re-checking the waterfall after the change

You need evidence that request start actually moved earlier.

Only checking the Lighthouse score

A score change does not prove discovery timing improved.

What Not to Fix Yet

If the LCP resource starts late, do not automatically:

Compress the image
Change the CDN
Upgrade hosting
Defer all JavaScript
Inline all CSS
Preload everything

Find the discovery dependency first.

Fix the Discovery Path, Not Just the Image

Root-cause pattern Direction
Critical resource hidden from initial HTML path Expose the critical resource earlier when architecture permits
CSS dependency Reconsider the critical resource representation or use preload when justified
JavaScript-generated resource Consider server-rendered or earlier markup exposure, or reduce the dependency when feasible
Lazy-loaded LCP resource Adjust loading behavior for the confirmed critical element
API-dependent hero Reduce the data dependency or expose the critical shell/resource earlier if possible
Priority issue after early discovery Investigate priority hints only after discovery is confirmed

This is a direction matrix, not a universal implementation checklist.

How to Verify Earlier Discovery

After changing the discovery path, verify the actual behavior rather than assuming the markup change worked.

Check:

  • the LCP element is still the expected candidate;
  • the exact resource request starts earlier;
  • the Initiator path changed as expected;
  • no duplicate request appeared;
  • the correct responsive candidate is still selected;
  • LCP actually improved under comparable conditions;
  • network competition did not increase enough to offset the gain;
  • layout, rendering and functionality did not regress.

Use the same page state and comparable lab conditions, then monitor field impact when available.

See verify the performance change.

Field vs Lab Impact

Late discovery is often easy to inspect in a controlled waterfall or trace.

Field impact still depends on real-user conditions such as:

  • connection quality;
  • device capability;
  • browser cache;
  • page variants;
  • user state;
  • traffic distribution.

Do not use one lab run to promise a specific field improvement.

Use lab evidence to prove the mechanism changed, then use field data when available to assess real-user impact.

When a Deeper LCP Investigation Is Needed

A deeper investigation is useful when:

The request starts late but Initiator evidence is ambiguous
JavaScript execution appears to control discovery
API and component timing overlap
The resource starts earlier after a fix but LCP barely changes
The LCP candidate changes between runs
A third-party dependency injects the final LCP element
Responsive candidate selection complicates preload decisions
Discovery and render delay both contribute

Late discovery is often visible in a waterfall, but the reason behind it may sit in HTML generation, CSS, JavaScript, a page builder, a framework or an API dependency. The useful question is not simply whether the resource starts late, but what prevented the browser from knowing about it sooner.

LCP resource starts late, but the dependency is still unclear?

A structured Core Web Vitals investigation can connect request timing, Initiator evidence, dependency chains and browser traces to identify what prevented the browser from discovering the critical resource earlier.

WebPerfLab — Measure → Trace → Diagnose → Fix → Verify

Final Takeaway

Late LCP discovery is a dependency problem before it is an image problem.

Ask:

  • When was the resource discovered?
  • What initiated it?
  • What dependency came before it?
  • Can the browser safely know about it earlier?

Then choose the smallest change that shortens the discovery path without creating unnecessary network work.

Identify→
Trace→
Confirm→
Expose Earlier→
Verify

Do not preload by reflex. Prove the dependency, shorten the discovery path, and verify the result.