Skip to content
Issue docs

Largest Contentful Paint image is lazy-loaded

Importantlcp_image_lazy_loadedIssue 188

What is this issue?

The Largest Contentful Paint (LCP) element is the biggest thing on the first screen -- usually the hero image. When that image carries loading="lazy", the browser does not request it until it has worked out the page layout, which delays exactly the moment LCP measures.

This check reports pages where the LCP element is an image and it is lazy-loaded.

Why it matters

  • It directly delays a Core Web Vital. Lazy-loading the LCP image is one of the most common causes of a poor LCP, and LCP is a ranking signal.
  • It is usually an accident -- a theme or plugin adding loading="lazy" to every image, including the first.
  • The fix is one attribute.

Fixing it removes an important-severity finding from the site's health score.

How to fix it

  1. Remove loading="lazy" from the LCP image:

    <img src="/hero.avif" fetchpriority="high" width="1200" height="675" alt="…">
  2. Add fetchpriority="high" so the browser requests it before other images.

  3. Fix it at the source. If a theme, plugin or image component lazy-loads every image, use its option to load the first one (or first few) eagerly -- for example priority on next/image.

  4. Keep lazy-loading the images below the fold.

Examples

1. A theme that lazy-loads everything

Fails:

<img src="/hero.jpg" loading="lazy" alt="The product on a desk">

Passes:

<img src="/hero.jpg" fetchpriority="high" alt="The product on a desk">

2. Text as the LCP element

Not applicable -- when the largest element on the first screen is a heading, there is no LCP image to lazy-load and nothing is raised.

How PixyScan detects this

  1. Chooses which pages to measure. After the crawl, PixyScan measures the homepage plus the pages your own site links to most, up to a per-scan budget (ten pages by default, at most fifty). Measuring every page would take hours and exhaust the PageSpeed Insights quota of the API key it runs under.

  2. Asks the PageSpeed Insights API about each of them, on mobile. This needs the Hobby plan or above and a PageSpeed Insights API key on the site or its workspace.

  3. Reads the Lighthouse audit lcp-lazy-loaded (in newer Lighthouse versions, the "lazy load not applied" item of lcp-discovery-insight), which checks whether the image that formed the Largest Contentful Paint in the lab run carried loading="lazy".

  4. Raises the issue when Lighthouse says the LCP image was lazy-loaded. When the LCP element is text or a video rather than an image, the audit is not applicable and nothing is raised.

    Lighthouse renamed several audits in versions 12 and 13 (the "insight" audits shared with Chrome DevTools). PixyScan reads whichever one the response carries, and the finding names the audit it was read from.

  5. Raises nothing on a page it did not measure. A page outside the sample, and a page whose measurement failed, are both reported as Not measured. Neither is treated as passing, and neither can fail this check.

What we store

Storage Level

Page Level


Database Table / Prisma Model

PagePerformance (page_performance), with the finding itself on audit_issues.details.


Fields Used

Field Type Description
strategy String mobile or desktop. Every number in the row belongs to one form factor.
fetchedAt DateTime When PageSpeed answered. "Measured three weeks ago" is not "not measured".
errorReason String? Why a sampled page still has no numbers. Null when the call succeeded.
audits Json? A compact summary of the Lighthouse audits the opportunity checks read: per audit its source (the Lighthouse audit id it was read from), score, numericValue, displayValue, itemCount, totals over every row (wastedBytes, wastedMs, blockingTime, mainThreadTime) and the five worst rows. Keyed by the classic Lighthouse audit id. Null when the response carried no audits.

On the finding (audit_issues.details): message, plus audit (lcp-lazy-loaded or lcp-discovery-insight) and items (the LCP element's HTML snippet).


Detection Dependencies

  • PageSpeed Insights API v5 (lighthouseResult.audits), mobile strategy
  • The PageSpeed plan feature (Hobby and above) and a PageSpeed Insights API key
  • The crawl's internal link graph, which decides which pages are sampled

Note

A page with no row was never measured. The pass samples the homepage plus the most-linked pages within a per-scan budget (default 10, at most 50), so most pages of a site have no page_performance row at all. That is the normal state, it is drawn as Not measured, and this check cannot be raised against it.

A row whose metric columns are all null with an errorReason set is a different state again: the page WAS sampled and the measurement failed. It is still never reported as passing.

Further reading