Quick Answer

Modern image formats like WebP and AVIF typically compress photos smaller than JPEG or PNG at the same visual quality, but the gap depends heavily on the image itself and the quality setting you choose, so treat any single percentage figure as a starting estimate rather than a guarantee. Serve the right size for each screen with srcset and sizes, wrap modern formats in a picture element with an older-format fallback, and add loading="lazy" to offscreen images so the browser skips downloading them until needed.

JPEG, PNG, WebP, AVIF: What Each Is For

Four formats cover almost every image on the web, and each has a job:

  • JPEG, lossy, built for photos with smooth gradients and lots of color variation. No transparency support.
  • PNG, lossless, built for flat colors, sharp edges, text, and transparency. Wastes space on photographic detail because it isn't throwing anything away.
  • WebP, supports both lossy and lossless compression in one format, plus transparency and animation, effectively covering what JPEG and PNG each do separately. WebP files are commonly smaller than equivalent JPEG or PNG files, though the exact gap depends on the image.
  • AVIF, newer, generally the smallest of the four at matching visual quality on photographic content, at the cost of slower encoding and less universal decode support in older software.

The mistake to avoid is treating this as "AVIF always wins, use it everywhere." What actually wins depends on what's in the image, which is worth testing rather than assuming.

What We Actually Measured

Rather than repeat a vendor percentage, we generated two test images and compressed each with Sharp, the image library behind most Node-based build pipelines, to see actual numbers.

A synthetic photo-like image (1200×800, gradient plus shapes plus film-grain-style noise) at matching quality-80 settings:

JPEG quality 80    146.9 KB
WebP quality 80     182.9 KB  (24.5% LARGER than JPEG)
AVIF quality 50      96.2 KB  (34.5% smaller than JPEG)

WebP came out larger than JPEG here, the opposite of the usual claim, because "quality 80" isn't a comparable number across formats; each codec's quality scale is its own scale. AVIF at a lower nominal quality number produced the smallest file at comparable visual quality.

A flat-color UI graphic (800×400, solid shapes and text, transparent background), the case PNG exists for, told a different story:

PNG lossless          5.7 KB
WebP lossless         2.2 KB  (60.8% smaller than PNG)
JPEG quality 90      10.3 KB  (larger, AND loses transparency)

Same four formats, opposite winner, because the content is different. That's the actual lesson: run your own images through your own pipeline before trusting a blanket number, including ours.

Serving the Right Size with srcset and sizes

srcset gives the browser several versions of an image and lets it pick, instead of everyone downloading one size meant for the largest screen:

<img
  srcset="photo-480.jpg 480w, photo-800.jpg 800w, photo-1200.jpg 1200w"
  sizes="(max-width: 600px) 100vw, 800px"
  src="photo-800.jpg"
  alt="Product photo"
>

The 480w, 800w, and 1200w are width descriptors, each image's actual pixel width, not a display size. sizes tells the browser how wide the image will actually be rendered at different viewport widths, so it can match a source to the real display size and device pixel ratio instead of guessing. Below a 600px viewport, the image fills the viewport (100vw); above that, it renders at a fixed 800px.

The plain src stays as a fallback for browsers that don't understand srcset, which by now is close to none, but costs nothing to include. Skipping sizes and providing only srcset is a common mistake: without it, the browser has to guess the display size before it has finished laying out the page, and that guess is frequently wrong on anything other than a full-width image.

The picture Element and Fallback Order

<picture> lets you offer a modern format first and fall back gracefully, rather than choosing one format for every browser:

<picture>
  <source srcset="photo.avif" type="image/avif">
  <source srcset="photo.webp" type="image/webp">
  <img src="photo.jpg" alt="Product photo" loading="lazy">
</picture>

The browser checks each <source> in order and uses the first one it supports, AVIF, then WebP, then falling through to the mandatory <img> at the end if neither modern format is understood. Order matters: put your smallest, newest format first, since that's the one browsers reach for whenever they can.

Every attribute that works on a plain <img>, alt, loading, width, height, belongs on that final fallback <img>, since it's the element that actually renders in every case, including the one where none of the <source> elements match.

Lazy Loading, and Its One Big Caveat

loading="lazy" on an <img> tells the browser to skip downloading that image until it's close to entering the viewport, instead of fetching every image on the page immediately regardless of whether the visitor ever scrolls that far:

<img src="footer-banner.jpg" alt="Seasonal offer" loading="lazy" width="1200" height="400">

It's a single attribute, needs no JavaScript, and is supported in every current browser. The one real caveat: it should never go on an image that's visible immediately when the page loads. The largest such image is very often the page's Largest Contentful Paint element, and lazy-loading it means the browser doesn't even start fetching it until after layout, which makes LCP worse, not better. Lazy loading is for images below the fold, not the hero image at the top.

The other easy win in that same snippet: explicit width and height let the browser reserve the right space before the image arrives, preventing the layout shift that shows up as a Cumulative Layout Shift penalty.

Frequently Asked Questions

Is WebP always smaller than JPEG? Not always. It depends on the image and the quality settings compared. In our own test, a photo-like image saved as WebP at quality 80 came out larger than the same image saved as JPEG at quality 80, because the two formats' quality scales aren't equivalent.
What's the difference between srcset and the sizes attribute? srcset lists the available image files with their actual pixel widths; sizes tells the browser how wide the image will actually display at different viewport widths, so it can pick the closest match from srcset.
In what order should picture sources be listed? Newest and smallest format first. The browser uses the first source whose type it supports, falling through to the final img if none match, so AVIF before WebP before the JPEG fallback is the usual order.
Should I lazy-load every image on the page? No. Skip loading="lazy" on any image visible without scrolling, especially the largest one, since that's usually the page's Largest Contentful Paint element and delaying its fetch makes that metric worse.
Does PNG ever beat modern formats like WebP? For photos, no; WebP and AVIF are built to beat PNG there. For flat-color graphics with transparency, WebP lossless usually still edges out PNG, but PNG remains a safe, simple choice and clearly beats forcing that same graphic into JPEG, which has no transparency support at all.