← Back to Blog
Performance·6 min read

Image Resizing for Web Performance: Pixel Density, Retina, and Responsive Images

How to size web images correctly for performance: understanding device pixel ratios, retina displays, srcset and sizes, and how to avoid both blurry uploads and bandwidth-wasting oversized assets.

Image resizing sounds trivial — change the dimensions, save the file. But the difference between a well-resized image and a poorly-resized one shows up in two places: how sharp it looks on phones, and how much data your visitors burn loading your site.

Get it right and your images look crisp on every device while loading fast. Get it wrong and you either ship pixelated images to retina users or waste 5–10× the bandwidth that a correctly-sized image would use.

This guide covers how to think about image sizing for the modern web.

The pixel density problem

Most of your visitors are on devices with high pixel density displays. A 2024-era iPhone has a 3× density display — every CSS pixel maps to 3×3 = 9 actual screen pixels. A Retina MacBook is 2×. Even mid-range Android phones and Windows laptops are typically 2×.

This means: if your image displays at 400 CSS pixels wide on a 3× phone, the device wants 1200 actual pixels of data.

Ship a 400-pixel image, and the phone has to upscale it 3× — it'll look blurry. Ship a 4000-pixel image, and the phone downsamples it down to 1200 — visually fine, but you wasted 90% of the bandwidth.

The right answer is 2× the displayed CSS size. That's enough for retina sharpness on virtually all devices, without overshooting too far.

What "displayed size" actually means

The displayed size depends on the layout and the screen width. A hero image might be:

  • 1200 px wide on a desktop (CSS pixels)
  • 800 px wide on a tablet
  • 400 px wide on a phone

Multiply each by 2× density and you get:

  • 2400 px wide for desktop retina
  • 1600 px wide for tablet retina
  • 800 px wide for phone retina

If you ship one image, you have to pick a size. Ship 2400 and phones waste bandwidth; ship 800 and desktops look soft.

The right answer: ship multiple sizes and let the browser pick.

srcset and sizes (the responsive image attribute)

HTML's srcset and sizes attributes let you give the browser several image options:

<img
  src="hero-1200.webp"
  srcset="
    hero-400.webp 400w,
    hero-800.webp 800w,
    hero-1200.webp 1200w,
    hero-1600.webp 1600w,
    hero-2400.webp 2400w
  "
  sizes="(max-width: 768px) 100vw, 1200px"
  alt="Hero image"
  loading="lazy"
>

The browser inspects:

  1. The current viewport width.
  2. The pixel density of the device.
  3. The sizes attribute (which tells it how big the image will display at that viewport).

Then it picks the smallest image in srcset that's large enough to look sharp. On a 3× phone, it might grab hero-1200.webp. On a desktop retina display, hero-2400.webp. On an old Windows laptop, hero-800.webp.

Total result: every device gets the smallest acceptable file. No bandwidth waste, no blurriness.

How to generate the sizes

You can generate responsive sizes manually with our free image resizer — upload a high-res original, set the percentage or pixel target, and download. Repeat for each size you want.

For automated workflows, build pipelines like Next.js's Image component or Cloudinary do this on the fly. But for static sites, manual generation works fine — just resize once and ship the variants.

A typical responsive set for a hero image:

  • 400 px wide (small phones)
  • 800 px wide (large phones)
  • 1200 px wide (tablets)
  • 1600 px wide (laptops)
  • 2400 px wide (desktop retina)

For thumbnails that display at ~200 px CSS:

  • 200 px (1× displays)
  • 400 px (2× retina)
  • 600 px (3× retina)

Resize before compressing

The order matters. Compressing a 4000-px image and then resizing it to 1200 px gives you a smaller-but-blurrier file than resizing first and then compressing. Always resize first.

The pipeline is:

  1. Highest-quality original (RAW, large PNG, etc.)
  2. Resize to target dimensions.
  3. Compress at quality 80–85.
  4. Convert to WebP/AVIF.
  5. Ship with srcset and sizes.

You can run the entire pipeline in your browser using our resizer, compressor, and converter — all in sequence, all free.

Don't upscale lossy images

If your original is 800 px wide, you can't get a sharp 2400 px version by resizing up. You'll just blur the existing pixels.

Two options if you need a larger version:

  • Get the original high-res file if it exists somewhere.
  • Use AI upscaling to reconstruct detail that the original didn't have. Try our AI upscaler — it uses Real-ESRGAN to predict plausible high-res detail.

AI upscaling is genuinely good in 2026, but it's not magic. Quality of the source still matters; you can't get a sharp 2400-px output from a 100-px source.

Aspect ratio matters as much as pixel count

Resizing without preserving aspect ratio stretches the image. Most resizers (including ours) lock the aspect ratio by default — unchecking it is almost always a mistake.

If you need to change aspect ratio (to match a platform's required dimensions), crop instead of stretch. Use a visual cropper to choose what part of the image to keep.

Stretching: 1200×800 → 1200×600 by squishing vertically.

Cropping: 1200×800 → 1200×600 by chopping the top or bottom.

The cropped version always looks better. Ratio mismatches in design contexts (an image meant to fit a 16:9 hero space, but the source is 4:3) almost always want a crop.

Image dimensions for common platforms

A practical reference for what to resize to:

  • Hero/landing images: 1920–2400 px wide, 16:9 or 21:9 aspect.
  • Blog post inline images: 1200 px wide is usually plenty.
  • Thumbnails: 400 × 400 (with 200×200 displayed).
  • Email body images: 600 px wide max (older email clients clip).
  • Profile pictures: 400 × 400.
  • OpenGraph / social previews: 1200 × 630.

Match your resize target to the actual displayed size, not "as big as possible."

Common resizing mistakes

  • Uploading the camera original: A modern camera produces 24 MP files (6000 × 4000). For most web uses, that's 5–10× more than you need. Resize first.
  • Resizing in a tool that doesn't preserve sharpness: Some resizers (especially old ones) use bicubic downscaling, which softens the image. Modern tools (Lanczos, ImageMagick) preserve sharpness much better. Our resizer uses high-quality canvas scaling.
  • Not resizing for retina: Shipping a 600-px image meant to display at 600 CSS pixels gives blurry results on every modern phone. Always 2×.
  • Stretching to a different aspect ratio: Always crop, never stretch.
  • Not removing EXIF data: Camera images include EXIF (orientation, GPS, camera info). Strip this before publishing for privacy and a small file-size saving.

A 60-second resize workflow

  1. Open the highest-quality original you have.
  2. Decide the largest displayed size on your site (e.g., 1200 px for a blog inline image).
  3. Multiply by 2× for retina (so 2400 px).
  4. Resize to 2400 px wide using our free resizer.
  5. Generate smaller variants for srcset: 1200 px, 800 px, 400 px.
  6. Compress each variant at quality 80–85, convert to WebP.
  7. Ship with srcset and sizes.

Bottom line

Right-sizing images is one of the highest-leverage things you can do for performance and UX. Resize before compressing. Always 2× for retina. Use srcset for multiple sizes.

A site that does this well loads twice as fast as one that doesn't, and looks sharp on every screen.

Free tools to run the workflow: our resizer, compressor, and format converter — all in your browser, no uploads, no signup.

More guides