DEV Community

Cover image for JPG vs PNG vs WebP: Which Image Format Should You Use in 2027?
Quick Image Fix
Quick Image Fix

Posted on

JPG vs PNG vs WebP: Which Image Format Should You Use in 2027?

Images are usually the heaviest thing on a page, and picking the wrong format is one of the easiest ways to make a site slower than it needs to be. I run into this constantly while building QuickImageFix, a free set of image tools, so here is the short version I wish I'd had years ago.

Disclosure: QuickImageFix is my own project. It's linked a couple of times below where it's relevant, and everything in the article works without it.

The short answer

  • Photos: use WebP (or AVIF if you can), with JPG as the fallback.
  • Logos, screenshots, UI with sharp edges or transparency: use PNG, or WebP lossless.
  • Icons and illustrations made of shapes: use SVG.
  • Short animations: use video or animated WebP instead of GIF when you can.

That covers most cases. The rest of this article explains why, and how to put it into practice.

What each format is good at

Format Compression Transparency Animation Best for
JPG Lossy No No Photos, universal compatibility
PNG Lossless Yes No Screenshots, logos, graphics with text
WebP Lossy or lossless Yes Yes Almost anything on the modern web
AVIF Lossy or lossless Yes Yes Photos where you want the smallest files
GIF Lossless, 256 colors 1-bit only Yes Legacy animations
SVG Vector Yes Yes (via CSS or SMIL) Icons, logos, simple illustrations

A few notes on that table:

  • JPG is still everywhere and works in every tool you can think of. It throws away detail you usually can't see, which keeps photos small, but it has no transparency and it gets blocky around sharp edges and text.
  • PNG keeps every pixel exactly as it was. That's great for a screenshot or a logo, and wasteful for a photo, where files can end up several times larger than the same image as JPG or WebP.
  • WebP handles lossy and lossless compression, transparency and animation in one format. At similar visual quality its files are often noticeably smaller than JPG or PNG, and all current major browsers support it.
  • AVIF often compresses photos even better than WebP, but encoding is slower and tooling is less universal. It's worth offering as a first choice in a <picture> element, with WebP and JPG behind it.

Exact savings depend on the image and the encoder settings, so test with your own files instead of trusting a single percentage.

A quick decision guide

Ask these questions in order:

  1. Is it made of shapes and flat colors (logo, icon)? Use SVG.
  2. Does it need transparency? Use WebP or PNG. Don't use JPG.
  3. Is it a photo? Use AVIF or WebP, with JPG as the fallback.
  4. Is it a screenshot with small text? Use PNG or lossless WebP, so the text stays crisp.
  5. Is it an animation? Use a muted looping <video> or animated WebP, not GIF, unless you must support something old.

Serving modern formats with fallbacks

The <picture> element lets the browser choose the best format it supports:

<picture>
  <source srcset="/images/hero.avif" type="image/avif" />
  <source srcset="/images/hero.webp" type="image/webp" />
  <img
    src="/images/hero.jpg"
    alt="Laptop on a desk showing a photo editor"
    width="1200"
    height="630"
    fetchpriority="high"
    decoding="async"
  />
</picture>
Enter fullscreen mode Exit fullscreen mode

Two details matter here:

  • Always set width and height (or an aspect ratio) so the browser can reserve space and avoid layout shift.
  • Add loading="lazy" to images below the fold, but not to your main hero image. Lazy-loading the largest visible image can hurt Largest Contentful Paint. Use fetchpriority="high" on that one instead.

Next.js: let the framework do it

If you use Next.js, the next/image component can convert and resize images for you. You can enable AVIF as well as WebP in next.config.js:

// next.config.js
module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
};
Enter fullscreen mode Exit fullscreen mode
import Image from 'next/image';

export default function Hero() {
  return (
    <Image
      src="/images/hero.jpg"
      alt="Laptop on a desk showing a photo editor"
      width={1200}
      height={630}
      priority
    />
  );
}
Enter fullscreen mode Exit fullscreen mode

The priority prop tells Next.js this image is above the fold, so it's preloaded instead of lazy-loaded. Leave it off for images further down the page.

Compressing and converting in the browser

You don't always need a server. The Canvas API can resize and re-encode an image on the client:

async function compressImage(file, { maxWidth = 1600, quality = 0.8, type = 'image/webp' } = {}) {
  const bitmap = await createImageBitmap(file);
  const scale = Math.min(1, maxWidth / bitmap.width);

  const canvas = document.createElement('canvas');
  canvas.width = Math.round(bitmap.width * scale);
  canvas.height = Math.round(bitmap.height * scale);

  const ctx = canvas.getContext('2d');

  // JPEG has no alpha channel, so fill with white to avoid black backgrounds
  if (type === 'image/jpeg') {
    ctx.fillStyle = '#ffffff';
    ctx.fillRect(0, 0, canvas.width, canvas.height);
  }

  ctx.drawImage(bitmap, 0, 0, canvas.width, canvas.height);

  return new Promise((resolve) => canvas.toBlob(resolve, type, quality));
}
Enter fullscreen mode Exit fullscreen mode

Check what you get back: canvas.toBlob falls back to PNG if the browser can't encode the format you asked for, so compare blob.type with the type you requested before you rely on it. Support for encoding WebP differs between browsers.

If you only need to shrink a few files and don't want to write code, a ready-made image size reducer does the same job in a couple of clicks.

Common mistakes

Saving a photo as PNG. It looks perfect and the file is huge. Convert photos to WebP or JPG.

Converting a transparent PNG to JPG. The transparent areas turn black or white, depending on the tool. Keep transparency with PNG or WebP, or fill the background deliberately first.

Recompressing the same JPG again and again. Every lossy save loses a little more quality. Keep an original, and export from it each time.

Using one huge image for every screen. A 4000 px photo on a phone wastes data. Serve several sizes with srcset or let next/image generate them.

Forgetting alt text. It helps screen reader users and gives search engines context, so describe what the image shows in a short sentence.

Uploading HEIC straight from an iPhone. Many sites and browsers can't display it. Convert to JPG or WebP first.

A note on transparent backgrounds

Many people searching for a "transparent PNG" actually need a background removed, not a format converted. Changing the file extension doesn't make a background transparent, because a JPG simply has no transparency to keep. You need to cut the subject out and export a format that supports alpha. That's the reason I built a GIF background remover alongside the image tools.

Wrapping up

  • Pick the format by content: SVG for shapes, WebP or AVIF for photos, PNG for crisp graphics and transparency.
  • Offer modern formats with <picture> or next/image, and keep JPG as the fallback.
  • Always set dimensions, lazy-load below-the-fold images, and prioritize your hero image.
  • Test with your own images, because savings vary from file to file.

If you have a format question I didn't cover, leave it in the comments. And if you'd like to try the tools mentioned above, they're free at QuickImageFix, available in 10 languages.

Top comments (0)