Images larger than their displayed size
What is this issue?
An image is oversized when the file is much bigger than the space it is shown in -- a 2400-pixel-wide photo displayed 400 pixels wide on a phone. The browser downloads every pixel and then throws most of them away.
This check reports pages where serving correctly sized images would save 4 KiB or more.
Why it matters
- Images are usually the heaviest part of a page, and oversized ones are the easiest bytes to remove.
- Mobile pays the most. A desktop-sized image sent to a phone over a mobile connection is the single most common cause of a slow Largest Contentful Paint.
- It costs on every view, not just the first.
Fixing it removes a standard-severity finding from the site's health score.
How to fix it
Serve several sizes and let the browser choose:
<img src="/hero-800.jpg" srcset="/hero-400.jpg 400w, /hero-800.jpg 800w, /hero-1600.jpg 1600w" sizes="(max-width: 600px) 100vw, 800px" width="800" height="450" alt="…">Use an image CDN or your framework's image component (
next/image, Nuxt Image, Cloudinary, imgix) to generate the sizes automatically.Resize uploads in your CMS to the largest size the layout can display.
Examples
1. A desktop hero on a phone
Fails -- 146 KiB of savings: a 1600x900 image displayed at 412x232.
<img src="/hero-1600.jpg" alt="…">Passes:
<img src="/hero-800.jpg" srcset="/hero-400.jpg 400w, /hero-800.jpg 800w"
sizes="100vw" alt="…">2. Poorly compressed but correctly sized
Not this check -- a logo served at its displayed size but saved as an uncompressed PNG. That is a compression problem, and is not counted here.
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
uses-responsive-images(in newer Lighthouse versions,image-delivery-insight), which compares each image's file size to the size it was displayed at on a mobile screen.Raises the issue when the total savings reach 4 KiB -- Lighthouse's own per-image floor, so in practice when Lighthouse lists any image.
image-delivery-insightcombines several image problems in one table. PixyScan counts only the images it flags as "larger than it needs to be for its displayed dimensions", and only that part of their savings -- a compression or format saving on the same image is not counted here.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 (uses-responsive-images or image-delivery-insight), wastedBytes, thresholdBytes (4096), fileCount and items (the five images with the largest savings).
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.