Image Compression and WebP Conversion for Faster Pages
Hero images and blog figures are still the heaviest bytes on many marketing sites. Converting a folder of PNGs to WebP is the highest-leverage compression step most teams skip — or overdo until logos look mushy. This article is a practical conversion playbook: when WebP wins, which quality to start from, and how to keep sharp UI chrome.
Why WebP (and when not)
WebP typically beats JPEG at similar visual quality for photos and beats PNG for many large non-transparent graphics. Browser support is no longer the blocker it was years ago. Prefer modern delivery:
| Source type | First try | Keep original when |
|---|---|---|
| Photos | WebP (or AVIF) | Print masters / archival TIFF |
| UI screenshots with text | WebP q=80–90 or PNG | Text becomes fuzzy at low q |
| Logos / icons | SVG first; else PNG | Soft WebP edges on brand marks |
| Transparency | WebP lossless or PNG | Odd encoder bugs on rare pixels |
AVIF can win on bytes but encodes slower and still needs a fallback path in some pipelines. WebP remains the default “one extra format” for most portfolios and docs sites.
Quality dial without guessing
Start around quality 75–85 for photographic heroes and inspect at 1× and 2× DPR. For screenshots with small text, bias higher (85–95) or stay PNG. Lossless WebP helps when you need pixel-exact UI but may not beat optimized PNG for small sprites.
# cwebp (libwebp)
cwebp -q 80 input.jpg -o output.webp
# sharper text-ish content
cwebp -q 90 screenshot.png -o screenshot.webp
# lossless
cwebp -lossless ui-panel.png -o ui-panel.webp
Compare file size and a side-by-side zoom on glyphs. A 40% size win that blurs a pricing table is not a win.
Responsive delivery beats one huge WebP
Compression without srcset still ships a 2400px asset to phones.
<img
src="/images/hero-800.webp"
srcset="/images/hero-800.webp 800w,
/images/hero-1200.webp 1200w,
/images/hero-1600.webp 1600w"
sizes="(max-width: 640px) 100vw, 800px"
width="1600"
height="900"
alt="Product dashboard on a laptop"
loading="lazy"
decoding="async"
/>
Generate widths from your layout’s real displayed sizes, not arbitrary “marketing large.” Set width and height (or CSS aspect-ratio) to avoid CLS.
Pipeline options
Squoosh / GUI: fine for a handful of assets; encode settings are visible.
CLI batch: cwebp, sharp in Node, or magick for mixed trees.
// sharp example
await sharp("in.png")
.resize({ width: 1200, withoutEnlargement: true })
.webp({ quality: 82 })
.toFile("out-1200.webp");
Build plugins: Astro/Vite image pipelines can emit WebP on demand — still review defaults for text-heavy PNGs.
Keep originals in a src/images/raw or design export folder; commit only derived web sizes if your repo policy prefers small clones.
Transparency, animation, and metadata
- Animated WebP exists but GIF/video may be clearer for long clips; measure CPU decode on mid phones.
- Strip EXIF/GPS from camera uploads before public WebP — privacy and bytes.
- Color profiles: convert to sRGB for web consistency unless you have a color-managed art workflow.
Caching and CDN
Fingerprinted filenames (hero.a1b2c3.webp) let you set long Cache-Control. Replacing hero.webp in place causes stale CDN ghosts. Prefer content hashes or versioned paths when you re-encode.
Acceptance checklist before merge
- Visual A/B at target size (not only full-resolution)
- Text and logo edges acceptable
-
srcset/sizesmatch layout - Dimensions reserved (no CLS)
- Fallback only if your audience matrix requires it
- Lighthouse/WebPageTest weight dropped without LCP regression from wrong preload
Bottom line
Convert photos and large raster art to WebP at a quality you inspect, generate a few widths, and reserve SVG/PNG for sharp brand marks. Compression is not a single cwebp -q 50 over a folder — it is choosing the format per asset class and shipping the right size to each viewport.
Before/after review ritual
Open original and WebP at 100% zoom on a mediocre laptop panel, not only a retina display. Check skin tones, gradients, and any overlay text. If marketing prefers slight softness for photos, write that down — do not leave each developer guessing quality 70 versus 85.
For UI, reject any lossy output that softens glyph edges. Designers will spot it immediately in QA, and you will reconvert under time pressure. Lossless WebP or PNG/SVG from the start is cheaper than arguing screenshots in Slack.