Image Optimization

How to Compress Images Without Losing Quality

What I actually do to shrink listing photos without wrecking them—settings, tools, and the gotchas that slowed my pages down.

Written by
Convert Magic Team
Published
Reading time
6 min
How to Compress Images Without Losing Quality

How to Compress Images Without Losing Quality

How to Compress Images Without Losing Quality

I was trying to ship a real estate landing page, but the hero slider took 5–6 seconds to paint on mobile. The culprit: 8MB photos straight from a DSLR. Here’s the exact workflow I use now to keep images sharp while slashing weight.

How I tested

  • Devices: 2021 M1 MacBook Pro + iPhone 14 on LTE
  • Assets: 12 listing photos (8–12MB JPGs), 3 logo/overlay PNGs with transparency
  • Goal: cut total weight by 70% while keeping text/edges crisp on Retina displays

Quick wins (do these first)

  • Resize to the biggest size you’ll actually display (e.g., 1600px wide for hero, 800px for cards).
  • Strip metadata (EXIF) and thumbnails.
  • Use JPG/WebP for photos, PNG/WebP for logos/overlays.
  • Aim for JPG quality 70–80 or WebP quality 60–70; preview at 100% zoom on desktop and phone.

My fast workflow

  1. Resize, then compress

    • convert input.jpg -resize 1600x -strip output.jpg (ImageMagick)
    • If you need transparency, keep PNG but resize first.
  2. Export to WebP when possible

    • cwebp output.jpg -q 70 -o output.webp
    • Fallback: serve the original JPG/PNG with the <picture> element for older browsers.
  3. Batch with a tiny Python helper (Pillow)

from pathlib import Path
from PIL import Image

def compress(path: Path, max_width=1600, quality=78):
    img = Image.open(path)
    if img.width > max_width:
        height = int(img.height * max_width / img.width)
        img = img.resize((max_width, height), Image.LANCZOS)
    params = {"optimize": True, "quality": quality}
    out = path.with_name(f"{path.stem}_compressed{path.suffix}")
    img.save(out, **params)
    return out

for file in Path("photos").glob("*.jpg"):
    print(compress(file))
  1. Ship responsive sources
    Use <picture> or srcset so phones aren’t forced to download desktop-width assets.

Where this approach can fail (and fixes)

  • Logos look fuzzy: keep them as PNG/WebP with no lossy compression; only resize to exact display size.
  • Banding on gradients: try a slightly higher JPG quality (80–85) or move to WebP/AVIF.
  • Heavy screenshots/UI captures: PNG/WebP beat JPG here; avoid over-compressing text.
  • CDN double-compressing: if your CDN optimizes on upload, skip local lossy compression to avoid artifacts.

The results I saw

  • Hero slider dropped from ~18MB to ~5MB with WebP at q70; visually identical on desktop and phone.
  • LCP went from 3.8s to 2.1s on LTE without changing layout.
  • Designers stopped sending 6000px images once they saw the before/after load tests.

If you only do one thing: resize to the largest real display width and export at WebP quality ~70. That alone usually cuts 50–70% without anyone noticing.

Ready to Convert Your Files?

Try our free, browser-based conversion tools. Lightning-fast, secure, and no registration required.

Browse All Tools