Offscreen images loaded up front
What is this issue?
Images below the fold -- further down the page than the first screen -- are downloaded as soon as the page starts loading, alongside the content the visitor actually sees. Lazy-loading tells the browser to wait until the visitor scrolls near them.
This check reports pages where Lighthouse finds offscreen images worth 2 KiB or more that could have been deferred.
Why it matters
- They compete with what matters. Every byte of a gallery at the bottom of the page is bandwidth the hero image and stylesheets did not get.
- Many visitors never scroll that far, so the download is pure waste.
- The fix is one attribute on most images.
Fixing it removes a standard-severity finding from the site's health score.
How to fix it
Add
loading="lazy"to images below the fold:<img src="/gallery-1.jpg" loading="lazy" width="800" height="600" alt="…">Never lazy-load the image at the top of the page -- that delays Largest Contentful Paint (see "Largest Contentful Paint image is lazy-loaded").
Give lazy images a width and height so the page does not shift when they arrive.
Check your CMS or theme. Most add
loading="lazy"automatically; make sure the setting is on.
Examples
1. A gallery further down the page
Fails -- 176 KiB of gallery images downloaded before the page had painted:
<img src="/gallery-1.jpg" alt="…">Passes:
<img src="/gallery-1.jpg" loading="lazy" width="800" height="600" alt="…">2. A footer logo strip
Fails -- twelve partner logos in the footer, 40 KiB together, loaded up front.
Passes -- the same logos with loading="lazy".
How PixyScan detects this
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.
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.
Reads the Lighthouse audit
offscreen-images, which lists each image that was outside the first screen and hidden at load, and that was at least 2 KiB.Raises the issue when the total bytes of those images reach 2 KiB -- the same per-image floor Lighthouse uses, so in practice when Lighthouse lists any image.
Recent Lighthouse versions retired this audit without a replacement. When a response does not carry it, this check has nothing to read and raises nothing -- the page is not treated as passing either.
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 audits (offscreen-images), wastedBytes, thresholdBytes (2048), fileCount and items (the five largest offscreen images).
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.