Website Image Optimization: How to Build Pages That Load Faster
Reduce unnecessary image bytes, serve responsive sizes, choose formats by content, and prioritize important images. Measure changes against real user performance.
Website image optimization makes image-heavy pages faster by reducing unnecessary image bytes, serving dimensions suited to each rendered slot, choosing formats for the content and required features, and helping important images load early. Start by asking whether an image request is needed at all. Then measure the page, make one change at a time, and compare visual quality and performance on representative devices.
There is no universally fastest image format or guaranteed speed gain. The result depends on the image, its encoded quality, rendered size, browser support, layout, and visitor device. Image work can improve Largest Contentful Paint (LCP) when an image is the LCP element, but LCP also includes other stages and can be text or video.
1. Measure the page before changing images
Record a baseline for the page on mobile and desktop. Use a lab audit to identify oversized files, late-discovered images, layout shifts, and loading behavior; then check field data to understand what visitors experience. Compare the same page and conditions before and after. If server response or scripts change at the same time, do not attribute the whole LCP difference to image optimization.
LCP measures when the largest visible image, text block, or video is rendered relative to navigation. Google’s web.dev guidance sets a good target at 2.5 seconds or less and a poor result above 4 seconds, evaluated at the 75th percentile separately for mobile and desktop. This is a user-experience threshold, not a promise that image changes alone will meet it. LCP includes connection setup, redirects, and server response delays as well as image transfer and rendering. See Largest Contentful Paint (LCP).
2. Remove image requests that do not need to exist
A simple background effect may be better expressed with a CSS gradient or another native technique than with a raster image. As web.dev’s Ilya Grigorik and Jeremy Wagner put it: “The very first question you should ask yourself is whether an image is, in fact, required to achieve the effect you are after.” Avoiding an unnecessary request also avoids its download and decoding work. See Choose the right image format.
Keep an image when it conveys content or when a photographic or illustrated result is needed. Do not replace meaningful imagery with CSS merely to reduce a request.
3. Choose a format for the image and its requirements
For photographs, compare JPEG, lossy WebP, and AVIF at settings that preserve acceptable visual quality at the actual display size. WebP and AVIF can produce smaller files than JPEG or PNG for some images, but there is no universal winner. Review the rendered result as well as file size.
| Need | What to evaluate |
|---|---|
| Photographic image | Compare JPEG, WebP, and AVIF at visually acceptable quality and the target display dimensions. |
| Transparency | Choose an encoding and delivery path that preserves the required transparency, and verify browser support for your audience. |
| Animation | Confirm the format supports the animation behavior you need and test in target browsers. |
| Broad compatibility | Check actual visitor browsers and provide an appropriate fallback where your delivery approach needs one. |
| Vector artwork or simple effects | Consider a vector or native CSS technique when it represents the artwork or effect well. |
Lossy compression changes image information. Judge artifacts on the image at the size visitors see, especially around text, sharp edges, gradients, faces, and fine detail. A format label is not a substitute for visual review. Read web.dev’s format guide and image performance guidance.
4. Serve responsive image candidates
Use srcset to offer width candidates and sizes to describe the image’s expected rendered slot. The browser can choose a candidate based on the slot and device pixel density. Keep src as a usable fallback.
<img
src="/images/article-800.jpg"
srcset="/images/article-400.webp 400w,
/images/article-800.webp 800w,
/images/article-1200.webp 1200w"
sizes="(max-width: 600px) 100vw,
(max-width: 1000px) 80vw,
800px"
width="800"
height="533"
alt="A developer reviewing an image on a laptop">
The width descriptors say what intrinsic width each file has; sizes estimates the rendered width for viewport conditions. Make those values reflect the real layout. If the image spans the viewport on a phone but occupies a narrower column on desktop, describe those cases. Supplying a desktop-sized image to a much smaller mobile slot can waste data; web.dev gives 2–4x more data as an example of this problem, not a universal saving estimate. See Serve responsive images.
Generate multiple variants when display contexts justify the added files and build complexity. For an automated build pipeline, Sharp can resize images in scripts; ImageMagick is useful for one-off command-line resizing. Hosted image services can also generate and deliver variants, but they are optional. Whichever method you use, verify the generated dimensions, output format, quality, and URLs.
5. Reserve layout space and set loading priorities
Set width and height attributes, or a stable aspect ratio, so the browser can reserve space before an image loads. This reduces layout movement. The dimensions should describe the image’s intrinsic ratio even when CSS changes its displayed width.
Lazy-load images that are below the fold and appropriate to defer:
<img
src="/images/related-story.webp"
width="640"
height="427"
loading="lazy"
alt="A related story illustration">
Do not add loading="lazy" to the hero or another image expected to be the LCP element. It can delay discovery of the page’s most important image. Use fetchpriority="high" sparingly on a truly important image; marking too many resources high priority can compete with fonts, scripts, and other work. If an LCP image is only introduced through CSS or JavaScript and is not discoverable in initial HTML, consider a preload with high fetch priority, then measure whether it helps. An unnecessary preload can compete for bandwidth. See Responsive images: Deliver your images and Optimize Largest Contentful Paint.
6. A practical optimization workflow
- Inventory the page. Find image requests, their transferred bytes, dimensions, formats, and whether they are visible early or below the fold.
- Identify the important image. Determine whether the likely LCP element is an image, text, or video. Check whether the image is discoverable from initial HTML.
- Remove unnecessary requests. Replace simple image effects with CSS or another appropriate native representation.
- Resize to the layout. Generate width candidates based on actual content slots; use
srcsetand accuratesizes. - Compare formats and quality. Test likely formats on representative photos, graphics, transparency, or animation. Review appearance and bytes.
- Set dimensions and loading behavior. Reserve space, lazy-load suitable offscreen images, and keep the likely LCP image discoverable and prioritized appropriately.
- Deploy and validate. Recheck lab results, field data, browser compatibility, image appearance, and errors across mobile and desktop.
7. Common problems and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| The mobile page downloads a very large image | Only one large asset is offered, or srcset/sizes does not describe the layout. |
Provide appropriately sized candidates and make sizes match the rendered slot. |
| The hero appears late | The likely LCP image is lazy-loaded, discovered late through CSS or JavaScript, or competing with too many high-priority resources. | Remove lazy loading from the hero; make it discoverable early. Consider a measured high-priority hint or conditional preload if it is hidden from initial HTML. |
| The page jumps while images load | Image dimensions or a stable aspect ratio are missing. | Set intrinsic width/height or CSS aspect-ratio. |
| New format images fail in some browsers | The delivery path assumes support that some visitors’ browsers do not have. | Check audience support and provide a fallback or negotiated delivery appropriate to the browsers you serve. |
| Images look soft or show artifacts | Compression is too aggressive, the selected candidate is too small, or the image is being enlarged. | Review at actual display size; raise quality or provide a larger candidate where needed. |
| Smaller files did not improve LCP | The LCP element may not be an image, or connection, redirects, server response, discovery, decoding, or rendering dominates. | Inspect the LCP element and its timing breakdown. Address the stage that actually delays rendering. |
| Preloading makes other content slower | Unneeded or excessive preloads compete for bandwidth and priority. | Remove speculative preloads and retain only those supported by measurement. |
8. Performance, reliability, and cost considerations
Image optimization has tradeoffs. More responsive variants can reduce bytes for common slots but increase storage, build time, and the chance of stale or missing files. Compression can reduce transfer size while harming visual quality. A CDN or hosted image service may handle resizing, caching, and format negotiation, but is not required for every site; compare its cost and operational convenience with build-time generation.
For reliability, keep a valid fallback where needed, verify generated asset paths during deployment, and monitor failed image requests. Test representative browsers and viewport sizes. For performance, compare both transfer bytes and user-facing outcomes: smaller image files do not translate into an equal reduction in LCP because LCP includes more than image transfer. Use field data segmented by mobile and desktop, and evaluate the 75th percentile against the web.dev threshold rather than promising a fixed gain.
9. Capture screenshots to review page changes
Screenshots can help compare visual output before and after changing image formats, responsive candidates, or layout dimensions. They show appearance at a selected viewport; they do not replace field performance data or tell you how quickly a real visitor’s page loaded.
For local checks, use browser developer tools or automation to capture the same URL at the same viewport before and after the change. Keep the viewport, device scale, page state, and wait condition consistent so the comparison is meaningful. For a hosted capture, ScreenshotNeo is a website screenshot API and MCP server for developers. Its one-call API can return a screenshot or PDF, and its documented options include device presets, full-page capture, waiting for a selector or network idle, and custom CSS. See ScreenshotNeo and the API documentation.
Or skip the browser setup
Make a screenshot request with cURL:
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com \
-o shot.webp
Or use Python:
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
Or use Node.js:
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://example.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
Replace YOUR_API_KEY with your key and https://example.com with the page URL. The returned capture can help inspect appearance at a point in time. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Image bytes and page speed still need to be measured with performance tools and real-user data.
Sign up free for 1,000 screenshots a month, no card required.
FAQ
Should every image be converted to AVIF?
No. Choose by content, transparency or animation needs, browser support, visual quality, and measured file size. Compare formats on representative images.
Does a smaller image file guarantee a faster LCP?
No. It can help when an image is the LCP element, but discovery, connection, server response, decoding, rendering, or a different LCP element may dominate.
Do I need an image CDN?
No. Build-time responsive variants can be enough. A hosted service is an option when its delivery and workflow features justify its cost and operational tradeoffs.
Should I lazy-load all images?
No. Lazy loading is for suitable below-the-fold images. Keep the likely LCP hero discoverable early.


