Performance
Images: the largest item in page weight
Which dimensions, which format and which loading behaviour your images need so they do not slow the page down — and how to find the heaviest files in a few minutes.
9 min read
By Timo Wessels Published
On most websites, images are the largest item in page weight — and the easiest one to shrink. Four things decide it: an image is no wider than the area it is shown in. It comes in a modern format, meaning WebP or AVIF. The browser loads only one version of it, not several. And the large image in the visible area is loaded with priority rather than deferred, with fixed dimensions so nothing jumps.
Why the images in particular?
The HTTP Archive measures millions of websites every year. In 2025, the median mobile home page carried 911 KB of images — more than any other kind of content, ahead of JavaScript and fonts. On around three quarters of mobile pages, an image is also the largest visible element during loading, which is exactly the element the loading metric LCP is measured on.
Anyone who wants to make a slow page faster should therefore look at the images first. Almost every image problem is a mix of four mistakes:
- Wrong dimensions. The image is 4,000 pixels wide and shown in an area 800 pixels wide. The browser loads all of it and scales it down.
- Old format. JPEG and PNG instead of WebP or AVIF.
- No compression. Even a WebP can be needlessly heavy.
- Several versions at once. Three variants of the same image sit in the HTML and are shown or hidden with CSS. All three get loaded.
The right dimensions
An image should be no wider than the area it is shown in — for high-resolution screens the file may have correspondingly more pixels, but not any number. The sensible widths follow from your own layout: from the breakpoints and the maximum content width of your site, not from a general table.
The same applies to small images on a small scale. A product image that appears at roughly the same size on every device does not need three versions.
A note on working with others: when you order images from a photographer or an agency, give them the target widths up front. Otherwise the files arrive straight from the camera, and someone has to do the work a second time.
The right format
| Format | For | What it brings |
|---|---|---|
| WebP | photos and graphics, the default choice | lossy 25 to 34 percent smaller than JPEG, lossless 26 percent smaller than PNG |
| AVIF | photos where every kilobyte counts | around 50 percent smaller than JPEG according to MDN |
| SVG | logos, icons, diagrams | vector graphics, scales without loss |
| JPEG, PNG | files for download, fallback | — |
WebP is the safe default: every current browser supports it. AVIF compresses even further and now also runs in all major browsers — Chrome since version 85, Firefox since 93, Safari since 16.1, Edge since 121. MDN names two limits: a fallback makes sense for older browsers, and AVIF does not render progressively but only appears once the file has fully loaded.
How far the web still is from this shows in the 2024 Web Almanac: JPEG and PNG together account for around 61 percent of all image requests, WebP for 12 percent, AVIF for 1 percent. Measured in bits per pixel, WebP at 1.3 is clearly leaner than JPEG at 2.0 and PNG at 3.8.
The conversion is best handled in WordPress by a plugin that converts and compresses automatically on upload. That matters more than converting the existing library once — otherwise in three months someone uploads a camera photo again and the problem is back.
How heavy may an image be?
There is no fixed limit, but there is a yardstick. According to the 2024 Web Almanac, the median image on the web weighs 12 KB, and the largest image on a page weighs 135 KB at the median. A large header image may sit above that because it dominates the display. A file in the megabyte range, on the other hand, is almost always a sign that the dimensions, the format or the compression is wrong.
Compare the file size not with a rule of thumb but with the display size: an image shown 800 pixels wide has no reason to be a 4,000-pixel file.
Load only one version
For images that should be cropped differently on different devices there is the <picture> element. The browser checks the <source> entries in order and takes the first one whose condition matches — exactly one file is loaded:
<picture>
<source media="(max-width: 576px)"
srcset="workshop-576.webp"
width="576" height="576">
<source media="(max-width: 960px)"
srcset="workshop-960.webp"
width="960" height="770">
<img src="workshop-1920.webp"
width="1920" height="893"
alt="Workshop with two workbenches">
</picture>
Two things you can get wrong:
- The order. Because the first match wins, with
max-widthconditions the smallest breakpoint goes at the top. If the widest condition comes first, it matches almost every device. - The
<img>at the end is mandatory. It describes the image, carries the alternative text and is the fallback when no<source>matches.
If the same image is only to be delivered at different resolutions without changing the crop, srcset with sizes directly on the <img> is enough. WordPress has generated this automatically since version 4.4 for images from the media library — a good reason to insert images through the media library rather than linking them by hand.
Defer loading — except the main image
Images that only become visible after scrolling do not have to load straight away:
<img src="reference.webp" loading="lazy" width="800" height="600" alt="…">
The exception matters: the large image in the visible area must not be lazy-loaded. web.dev states explicitly not to lazy-load images that are likely to be in the viewport on load, and especially not the LCP image. Even so, according to the 2025 Web Almanac, 16 to 17 percent of pages do.
What is right there is the opposite, high loading priority:
<img src="header.webp" fetchpriority="high" width="1920" height="893" alt="…">
On Google Flights, this brought LCP down from 2.6 to 1.9 seconds. Since version 6.3, WordPress sets fetchpriority="high" itself on the image it considers the LCP image and leaves lazy loading off there. The mistake usually comes from plugins or site builders that switch every image to lazy loading across the board. After every such installation, check that the header image is excluded.
Images and jumping layouts
Put width and height on every image. Not as a design instruction but as information for the browser: it calculates the aspect ratio from them and reserves the space before the image arrives. Without them, everything below jumps as soon as the image loads. According to the 2025 Web Almanac, 62 percent of mobile pages have at least one image without dimensions.
To keep the image flexible anyway:
img {
max-width: 100%;
height: auto;
}
The attributes reserve the space, the CSS makes the image adaptable.
A related case: elements hidden with display: none that appear later — notice bars, banners, content loaded afterwards. They take up no space beforehand and push everything down when they appear. Reserve the space from the start, for example with min-height, or hide the element with opacity: 0, so it keeps its space.
The special case of background images
Images set as a background in CSS behave differently:
- They are not in the HTML and carry no alternative text. For decoration that is right; for images with content it is wrong.
- The browser only discovers them once it has processed the CSS. If a background image is the LCP element, web.dev says it needs a
preload, ideally withfetchpriority="high". loading="lazy"does not work there — the attribute belongs on the<img>element, not in CSS.
As a rule: decoration may be a background image. Content belongs in the HTML.
How to check it yourself
- The Network tab. Open the developer tools (F12), Network tab, filter "Img", reload the page, sort by size. Your problem images are at the top. There you also see whether several versions of the same image are loaded.
- The right-click. "Open image in new tab" shows the real dimensions. Compare them with the width at which the image appears on the page.
- PageSpeed Insights. Since Lighthouse 13, the former separate checks for format, size and compression are combined into one insight, "Improve image delivery". It lists the affected files with the possible saving in kilobytes.
- The throttling test. Set a slow connection in the Network tab and reload. In slow motion you see which image loads late and what shifts as it does.
- The media library. Look through it in WordPress for large files. Anything in the megabyte range is a candidate.
What to do
- Set up automatic processing on upload: conversion to WebP or AVIF, compression, size variants. That stops the problem from coming back.
- Take on the ten largest images, not all of them. A few files usually make up most of the weight.
- Check the header image separately: the right size,
fetchpriority="high", noloading="lazy", dimensions set. - Put
widthandheighteverywhere — especially on images from site-builder blocks and hand-written HTML. - Clean up the library: duplicate uploads and images from pages that no longer exist. That makes the media library and the backup smaller.
And one expectation to set straight: image optimisation is not a one-off job. It is a setting that is made correctly once, plus a habit with every new image. Without both, the site is back where it started after a year of content updates.
Sources
- HTTP Archive, Web Almanac 2025, Page Weight — 911 KB of images on the median mobile home page, images as the largest item: almanac.httparchive.org
- HTTP Archive, Web Almanac 2025, Performance — images as the LCP element, 16 to 17 percent lazy-loaded LCP images, 62 percent with unsized images: almanac.httparchive.org
- HTTP Archive, Web Almanac 2024, Media — format shares, bits per pixel, 12 KB and 135 KB at the median: almanac.httparchive.org
- Google for Developers, An image format for the Web — WebP 25 to 34 percent smaller than JPEG, 26 percent smaller than PNG: developers.google.com
- MDN, Image file type and format guide — AVIF around 50 percent smaller than JPEG, browser support, no progressive rendering, SVG for graphics: developer.mozilla.org
- MDN, the
<picture>element — source selection, role of the<img>: developer.mozilla.org - WordPress Core, Responsive Images in WordPress 4.4 — automatic
srcsetandsizes: make.wordpress.org - web.dev, Browser-level image lazy loading — no lazy loading for visible and LCP images, no
loadingfor CSS backgrounds: web.dev - web.dev, Optimize resource loading with the Fetch Priority API — Google Flights 2.6 to 1.9 seconds,
preloadfor background images: web.dev - WordPress Core, Image performance enhancements in WordPress 6.3 — automatic
fetchpriorityfor the LCP image: make.wordpress.org - web.dev, Optimize Cumulative Layout Shift —
widthandheight, reserving space for late content: web.dev - Chrome for Developers, Properly size images — part of "Improve image delivery" since Lighthouse 13: developer.chrome.com