Skip to content
Images 8 min read

Image Compression: WebP, JPEG, PNG — The Developer's Optimization Guide

Learn how lossy and lossless compression work, when to choose WebP vs JPEG vs PNG, how to compress images in the browser, and how image size affects Core Web Vitals.

ToolsVito Team

Lossy vs Lossless Compression

Lossy compression permanently removes image data to reduce file size. Quality can be tuned — higher quality = larger file. Some degradation is invisible at typical display sizes; extreme compression produces visible artifacts. JPEG and WebP support lossy modes.

Lossless compression reduces file size by encoding patterns more efficiently without discarding any data. The decoded image is pixel-perfect identical to the original. PNG and WebP lossless fall here — but lossless files are larger than lossy at equivalent visual quality.

Format Comparison

  • JPEG: Lossy, no transparency, excellent for photographs. Quality 75–85 gives an invisible-to-most-eyes result at 30–50% of the original size.
  • PNG: Lossless, supports transparency. Best for logos, icons, screenshots, images with sharp lines or text. PNGs of photographs are large — don't use PNG for photos.
  • WebP: Both lossy and lossless modes. At quality 80 lossy, typically 25–35% smaller than JPEG. Supports transparency. Support: all modern browsers (Chrome, Firefox, Safari 14+).
  • AVIF: New format based on AV1 codec. 30–50% smaller than WebP at equivalent quality. Slower to encode. Growing browser support (Chrome 85+, Firefox 93+, Safari 16+).
  • SVG: Vector format — infinitely scalable, very small for logos and icons. Not suitable for photographs.

Compression in the Browser (Canvas API)

async function compressImage(file, quality = 0.8) {
  return new Promise((resolve) => {
    const img = new Image();
    img.onload = () => {
      const canvas = document.createElement("canvas");
      canvas.width = img.naturalWidth;
      canvas.height = img.naturalHeight;
      canvas.getContext("2d").drawImage(img, 0, 0);
      canvas.toBlob(resolve, "image/webp", quality);
    };
    img.src = URL.createObjectURL(file);
  });
}

// Usage
const compressed = await compressImage(file, 0.8);
console.log(`Original: ${file.size} bytes, Compressed: ${compressed.size} bytes`);

Responsive Images with srcset

<!-- Serve the right size image for each device -->
<img
  src="hero-800.webp"
  srcset="hero-400.webp 400w, hero-800.webp 800w, hero-1200.webp 1200w"
  sizes="(max-width: 600px) 100vw, 800px"
  alt="Hero image"
  loading="lazy"
  decoding="async"
/>

Modern Format with Fallback

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

Core Web Vitals Impact

Images directly affect Largest Contentful Paint (LCP) — Google's measure of when the main content loads. LCP under 2.5s is "good". Optimizing the hero image is typically the highest-impact LCP improvement:

  • Convert to WebP/AVIF: -30–50% file size
  • Add correct width and height attributes: prevents layout shift (CLS)
  • Use loading="lazy" on below-fold images: reduces initial page weight
  • Use fetchpriority="high" on the LCP image: tells browser to prioritize it

Compress Images Instantly

Use ToolsVito's Image Compressor to compress JPEG, PNG, and WebP files in your browser — no upload to a server, no file size limits beyond your RAM.

Try it now — free, runs in your browser

Image Compressor

Shrink JPG, PNG & WebP