Guide
How to Compress Images for the Web Without Losing Quality
Updated March 2026 · 8 min read
By CompressLocal Team
Page speed is a ranking factor. Images are usually the heaviest assets on a web page — often 50-80% of total page weight. Compressing them properly can cut load times in half without any visible difference in quality.
1. Pick the right format
Not every format is suited for every image type:
| Format | Best for | Compression |
|---|---|---|
| JPEG | Photos, gradients, complex images | Lossy — adjustable quality |
| PNG | Screenshots, text overlays, transparency | Lossless — larger files |
| WebP | Everything (modern browsers) | Lossy + lossless — 25-35% smaller than JPEG |
2. Target the right file size
For most websites, these are good target sizes per image:
- Hero images: under 200 KB
- Content images: under 100 KB
- Thumbnails: under 30 KB
- Icons and logos: use SVG when possible, otherwise under 10 KB
A total page weight of 1-2 MB (including all assets) is a good benchmark. Google's Core Web Vitals penalize pages where the Largest Contentful Paint (LCP) element takes too long to load.
3. The compression workflow: resize, compress, then choose format
Order matters. The most efficient workflow is: resize first, compress second, then convert to the optimal format last. Here's why this sequence saves the most bytes:
Resize first. A 4000x3000 photo displayed in an 800px-wide container wastes bandwidth on pixels the browser throws away. Resizing that image to 1200x900 (1.5x the display width for retina screens) can drop the file from 5 MB to under 500 KB before you touch quality settings. This single step often delivers the biggest reduction.
Compress second. With the dimensions already right-sized, apply quality-based compression. For JPEG and WebP, reducing quality from 100 to 80 cuts file size by 60-70% with minimal visible difference. The sweet spot for most web images is 70-85 quality. Going below 60 introduces noticeable artifacts, especially around text and sharp edges.
Choose format last. Once the image is resized and compressed, convert to the best delivery format. WebP is 25-35% smaller than an equivalent-quality JPEG. AVIF can save another 20% on top of WebP, but encoding is slower and browser support is still catching up. If you compress before resizing, you waste CPU cycles processing pixels that will be discarded.
4. Use quality-based compression
For JPEG and WebP, reducing quality from 100 to 80 cuts file size dramatically with minimal visible difference. Going below 60 introduces noticeable artifacts. The sweet spot for most web images is 70-85 quality. At quality 80, a typical 1200px-wide photo compresses to around 80-120 KB — well within the target range for content images.
5. Responsive images and srcset
Compressing a single image isn't enough if you're serving a 1200px-wide file to a 375px-wide phone screen. The HTML srcset attribute lets you provide multiple sizes so the browser picks the best one for the current viewport and pixel density.
A typical setup looks like this: generate your image at 400px, 800px, and 1200px widths. Then use srcset="img-400.webp 400w, img-800.webp 800w, img-1200.webp 1200w" combined with a sizes="(max-width: 600px) 100vw, 800px" attribute. The browser calculates which file to download based on the viewport width and device pixel ratio — a phone on a 375px screen fetches the 400w version (about 35 KB), while a desktop gets the 1200w version (about 110 KB).
For format negotiation, wrap your images in a <picture> element. Add a <source> with type="image/webp" and another with type="image/jpeg" as a fallback. Browsers that support WebP download the smaller file; older browsers fall back to JPEG. This combination of srcset and picture can reduce image transfer sizes by 40-60% compared to serving a single large JPEG to every device.
6. Lazy loading
Not every image needs to load immediately. The native HTML attribute loading="lazy" tells the browser to defer loading images until they're near the viewport. It's supported in all modern browsers and requires zero JavaScript.
Add loading="lazy" to every image except the LCP element — your hero image or the first visible image above the fold. Lazy-loading the LCP image actually hurts performance because the browser delays the most important paint. For a typical blog post with 5 images, the hero loads eagerly while the remaining 4 load on scroll. This can save 300-500 KB of initial page weight, directly improving Time to Interactive and First Contentful Paint scores.
7. CDN-level optimization
Even after local compression, a CDN can squeeze out additional savings automatically. Cloudflare Polish, for example, re-compresses images on the edge and can convert them to WebP on the fly based on the visitor's browser Accept header. AWS CloudFront paired with Lambda@Edge can do the same — intercepting image requests and returning optimized variants without changing your origin server.
Cloudflare Polish in "lossy" mode typically reduces JPEG files by another 10-15% beyond what local tools achieve. The "WebP" mode converts eligible images automatically, saving an additional 25-30% for visitors on Chrome, Edge, and Firefox. If you're on AWS, services like CloudFront Functions or imgproxy behind CloudFront can resize and compress on demand using URL parameters — no need to pre-generate every size variant.
8. Compress without uploading
Many online compressors require you to upload images to their servers. That's unnecessary — modern browsers can handle compression locally using the Canvas API and Web Workers.
9. Serve with proper caching
After compressing, make sure your server sends proper cache headers. For static assets with hashed filenames, use Cache-Control: public, max-age=31536000, immutable. For HTML and other mutable files, use max-age=0, must-revalidate.
10. Measuring the impact
Compression without measurement is guesswork. Three free tools give you concrete before-and-after numbers:
- Lighthouse (built into Chrome DevTools) — run an audit on your page and check the "Properly size images" and "Serve images in next-gen formats" opportunities. It estimates exact byte savings per image.
- PageSpeed Insights (pagespeed.web.dev) — uses real Chrome User Experience Report (CrUX) data alongside a Lighthouse run. Look at the LCP metric specifically: a well-compressed hero image can move LCP from 3.5s to under 2.0s on a 4G connection.
- WebPageTest (webpagetest.org) — provides waterfall charts showing exactly when each image starts and finishes loading. Run a test from a mobile device on a 3G connection to see worst-case performance. The "Content Breakdown" pie chart shows what percentage of your page weight is images.
Run these tools before and after compressing. Screenshot the results so you can show stakeholders the improvement — nothing sells optimization work like a Lighthouse score jumping from 62 to 94.
Real-world example: a blog post with 5 images
Here's a typical scenario. A blog post has 5 images: one hero banner (2400x1600, 1.8 MB JPEG), three content photos (each around 3000x2000, ~700 KB each), and one infographic PNG (1.2 MB). Total image weight: 4.2 MB.
After applying the workflow — resize to display dimensions, compress at quality 80, convert to WebP — the results look like this: the hero drops to 145 KB, each content photo lands around 85 KB, and the infographic compresses to 110 KB. New total: 680 KB. That's an 84% reduction in image weight, cutting the full page load from 5.1 MB to 1.6 MB. On a 4G mobile connection (roughly 10 Mbps), this shaves about 2.8 seconds off load time.
Add lazy loading for the 4 below-fold images and the initial page weight drops further to around 400 KB — the browser only fetches the hero image and the HTML on first load. The remaining images stream in as the reader scrolls.
Summary
- Resize to display dimensions first
- Compress to a target quality (70-85 for most images)
- Choose the right format (WebP when possible, AVIF for cutting edge)
- Use srcset and the picture element for responsive delivery
- Lazy-load everything except the LCP image
- Let your CDN handle format negotiation and edge compression
- Use a privacy-respecting tool that works locally
- Serve with immutable cache headers
- Measure with Lighthouse, PageSpeed Insights, and WebPageTest
Try it now — free, private, no signup
CompressLocal runs entirely in your browser. Drop your images, pick a target size, and download — nothing is ever uploaded.
Compress images now