Optimizing Images for Web Performance
Optimizing Images for Web Performance êŽë š
Images make websites look great, but theyâre also the biggest performance bottleneck. They add huge file sizes, delay Largest Contentful Paint (LCP), and can even mess with Cumulative Layout Shift (CLS) if they arenât handled properly. And while developers are quick to optimize JavaScript and CSS, images are often ignoredâdespite being the heaviest assets on most pages.
So, how do we make images fast, responsive, and efficient? Hereâs how:
Choose the Right Image Format
The format of an image has a massive impact on its size and loading speed. Picking the wrong one can easily double or triple your image payload. Check out this illustration:

To the user, itâs the exact same image, but the browser has to download 2x-10x more data depending on the format you pick.
Have a look at this photograph:

Photographs are quite a bit more complex than illustrations (usually), and the best formats can change. Notice how JPG is smaller than PNG this time, but modern formats like WebP and AVIF are still way smaller.
- JPG: Best for photos with lots of colors and gradients. Uses lossy compression to keep file sizes small.
- PNG: Best for graphics, logos, and transparency. Uses lossless compression, but files can be huge.
- WebP: A modern format thatâs often smaller than JPG and PNG while keeping quality high.
- AVIF: Even better compression than WebP, but not universally supported yet.
A good rule of thumb: JPG for photos, PNG for graphics, and use WebP or AVIF where possible for modern browsers.
Use Responsive Images
Not all users have the same screen size, so why serve the same massive image to everyone? Responsive images let you deliver the right image size based on the userâs device, reducing unnecessary downloads and improving load times.
Instead of a single <img>
 tag, try using a <picture>
 with the srcset
 and sizes
 attributes to tell the browser which image to load:
In this example, any screen less than 1400px wide will use an image from the srcset
that is at least 100% of the viewportâs width. So if the screen is 1100px wide, the browser will select and download the hero-desktop-1024
version. This automatically scales images to match different devices, saving bandwidth and improving loading speed for smaller screens.
Lazy-Load Below the Fold
One of the worst offenders for slow performance? Loading every image on the page at onceâeven ones that arenât visible. This is where lazy-loading comes in. Adding loading="lazy"
to an <img>
prevents it from downloading until itâs about to be seen.
<img
src="downpage-callout.jpg"
loading="lazy"
height="300"
width="300"
>
Itâs very important to specify the height
 and width
 attributes of images, especially if they are going to be lazy-loaded. Setting these dimensions letâs the browser reserve space in your layout and prevent layout shifts when the content loads. For more about layout shifts and how to prevent them, check out this deep dive on Cumulative Layout Shift.
For images that are critical for rendering, like your LCP element, you should override lazy-loading with fetchpriority="high"
. This tells the browser to load it ASAP.
<img
src="downpage-callout.jpg"
fetchpriority="high"
height="300"
width="300"
>
Serve Images from a CDN
AÂ Content Delivery Network (CDN)Â stores images in multiple locations worldwide, so they load from the nearest server instead of your origin. This speeds up delivery and reduces bandwidth costs.
CDNs use modern HTTP Protocols
Most CDNs will also speed up your images by serving them with modern protocols like HTTP/3, which has significant performance improvements over both HTTP/1 and HTTP/2. Check out this case study on HTTP/3 performance.
HTTP Caching headers
Users always have to download an image at least once, but HTTP caching headers can help repeat visitors load them much faster. HTTP Caching headers instruct the browser to hold onto the image and use it again, rather than asking for it from the CDN again on the next visit. Hereâs an example:
Cache-Control: public, max-age=31536000, immutable
This tells the browser that this image wonât change, and that it can be kept locally for 1 year without needing to be requested again. Caching isnât just for imagesâit speeds up all static assets. If youâre not sure if your caching is set up correctly, thereâs a full guide on HTTP caching that explains how to check and optimize it.
Wrapping Up
Images are one of the biggest opportunities for improving performance. By choosing the right format, compressing efficiently, lazy-loading, and leveraging CDNs with modern protocols, you can massively speed up your site.
If youâre looking for more image optimization tips, with detailed breakdown and real-world examples, check out the complete guide to optimizing website images.