Updated: June 9, 2026
To compress WebP images, choose lossy mode for photos and a starting quality around 75–85, or lossless mode for logos and sharp graphics. Use cwebp when you need precise control from the command line, Sharp when you want automation inside a Node.js build pipeline, and an online compressor for quick one-off files. The goal is not the smallest possible file at any cost—it is the smallest file that still looks correct at the size users actually see on the page.
Key Takeaways
- Lossy WebP at quality 75–85 produces files significantly smaller than JPEG with no visible quality drop at typical screen sizes.
- According to Google's own lossless study on 12,000 web images, lossless WebP is 23% smaller than ZopfliPNG and 42% smaller than standard libpng output.
cwebpis the most flexible tool; for Node.js projects, Sharp handles WebP, AVIF, and resizing in one pipeline.- When the image is your page's LCP resource, compressing it and sizing it correctly can directly improve LCP time.
- Never recompress lossy files. Always compress from the original source image (PNG, TIFF, or RAW).
- Resize images to their actual display dimensions before encoding—serving an oversized image wastes bandwidth regardless of compression.
Why WebP Compression Matters for Website Speed
Images are consistently one of the largest contributors to page weight. When images are unoptimized JPEGs or PNGs, the browser spends more time downloading them, and the Largest Contentful Paint metric climbs. HTTP Archive's Page Weight report tracks image bytes separately and shows images remain the dominant resource category for most pages.
WebP, developed by Google, addresses this with both lossy and lossless modes in a single format:
| Metric | WebP Lossy vs JPEG | WebP Lossless vs PNG |
|---|---|---|
| File size reduction | Significantly smaller (per Google compression study) | 23% smaller than ZopfliPNG; 42% smaller than libpng |
| Quality at equivalent size | Comparable or better | Pixel-identical |
| Transparency support | Yes (with alpha channel) | Yes |
| Browser support | Widely supported across modern browsers | Widely supported across modern browsers |
Sources: Google WebP lossless study, Can I Use — WebP.
With all major browsers—Chrome, Firefox, Safari, Edge, Opera—supporting WebP, there is no longer a practical reason to skip it. Check Can I Use for the latest support data before setting any organizational policy.
Lossy vs Lossless WebP: Which to Choose
Lossy WebP — Best for Photos and Hero Images
Lossy compression discards some visual data to achieve much smaller files. At quality 75–85, the difference is virtually invisible to the human eye, but the file size savings are significant.
Use lossy WebP when:
- The image is a photograph, background, or hero banner.
- The page renders many images (product grids, galleries, carousels).
- You need the smallest possible download size.
Google's cwebp defaults to quality 75 for lossy encoding. Most developers find the sweet spot between 75 and 85. Above 85, file sizes increase quickly for minimal perceptible gain.
Lossless WebP — Best for Icons, Logos, and Sharp Graphics
Lossless compression preserves every pixel exactly. The file is still smaller than PNG—Google's study shows 23–42% smaller depending on the PNG encoder being compared—but larger than lossy WebP.
Use lossless WebP when:
- The image contains text, sharp edges, or fine line work.
- It is an icon, logo, or UI element where pixel-perfect rendering matters.
- The image has large flat-color areas (lossless handles these especially well).
Near-Lossless — The Middle Ground
WebP also offers a near-lossless mode (-near_lossless in cwebp, level 0–100). It applies minimal preprocessing to improve compressibility while keeping visual quality nearly identical. A typical value is around 60. This is useful when you want files smaller than strict lossless but cannot tolerate visible artifacts.
How to Compress WebP Images with cwebp Commands
Google's cwebp is the reference encoder from the libwebp project. It runs on macOS, Linux, and Windows, and gives you full control over every compression parameter.
Install cwebp
On macOS:
brew install webp
On Ubuntu/Debian:
sudo apt install webp
On Windows, download the prebuilt binaries from the libwebp releases page.
Basic Lossy Compression
cwebp -q 80 input.png -o output.webp
The -q flag sets quality from 0 to 100. Default is 75. For most web photos, 80 is a strong starting point.
Lossless Compression
cwebp -lossless -z 6 input.png -o output.webp
The -z flag controls the lossless effort level (0 = fastest, 9 = slowest but smallest). A good default is -z 6.
Near-Lossless Compression
cwebp -near_lossless 60 -q 80 input.png -o output.webp
Preset Options for Different Content
cwebp includes presets tuned for specific image types:
cwebp -preset photo -q 80 photo.jpg -o photo.webp
cwebp -preset icon -lossless icon.png -o icon.webp
cwebp -preset text -lossless diagram.png -o diagram.webp
Available presets: default, photo, picture, drawing, icon, text. Place the preset first in the command, as it overrides other parameters except -q.
Batch Compress a Directory
for f in ./images/*.{jpg,png}; do
cwebp -q 80 "$f" -o "${f%.*}.webp"
done
Key cwebp Options Reference
| Flag | Purpose | Range | Default |
|---|---|---|---|
-q | Quality (lossy) | 0–100 | 75 |
-lossless | Enable lossless mode | flag | off |
-z | Lossless effort level | 0–9 | n/a |
-near_lossless | Near-lossless preprocessing | 0–100 | 100 (off) |
-m | Compression method (speed vs size) | 0–6 | 4 |
-alpha_q | Alpha channel quality | 0–100 | 100 (lossless) |
-preset | Content-type tuning | see above | default |
-resize W H | Resize before encoding | pixels | none |
-mt | Multi-threaded encoding | flag | off |
Full flag documentation: developers.google.com/speed/webp/docs/cwebp
Best Ways to Compress WebP Without Installing Software
If you prefer not to use the command line, several browser-based tools handle WebP compression well.
| Tool | Best For | Controls | Notes |
|---|---|---|---|
| Squoosh | Visual comparison, one-off files | Quality slider, side-by-side preview | Free, open-source, runs in browser |
| TinyPNG | Quick batch uploads | Automatic lossy | Check the site for current upload limits |
| LessMB | Quick online compression of WebP, JPEG, PNG | Simple upload workflow | Useful when you need to optimize a few images without installing tools |
| Compress-or-Die | Fine-grained cwebp-like control | Quality, method, alpha settings | Good for users who want terminal-level control in a browser UI |
| Squoosh CLI | Automation without Node.js | CLI flags | Uses same codecs as browser Squoosh |
When not to use online tools: for production workflows processing hundreds of images, or where source images are confidential. In those cases, use cwebp scripts or Sharp with a build pipeline.
Compress WebP Programmatically with Sharp
For Node.js projects, Sharp is a widely used image processing library. It converts and compresses images to WebP (and AVIF) with a concise API.
Install
npm install sharp
Compress a Single Image to WebP
import sharp from 'sharp';
await sharp('input.png')
.webp({ quality: 80 })
.toFile('output.webp');
Lossless WebP with Sharp
await sharp('logo.png')
.webp({ lossless: true })
.toFile('logo.webp');
Resize and Compress in One Step
await sharp('hero.jpg')
.resize(1200, 630, { fit: 'cover' })
.webp({ quality: 80 })
.toFile('hero.webp');
Resizing before encoding is important: a 2400-pixel source served to a 600-pixel container wastes bandwidth even after compression. Sharp strips metadata by default; see the Sharp metadata documentation if you need to preserve it.
Batch Processing Script
import sharp from 'sharp';
import { glob } from 'glob';
const files = await glob('./src/images/*.{jpg,png}');
for (const file of files) {
const output = file.replace(/\.(jpg|png)$/, '.webp');
await sharp(file)
.webp({ quality: 80 })
.toFile(output);
console.log(`${file} → ${output}`);
}
Sharp integrates with Vite, Webpack, Next.js, Astro, and other build tools, making it straightforward to automate WebP compression as part of your deployment pipeline.
How to Automate WebP Compression in a Website Workflow
Next.js
Next.js supports WebP out of the box through its Image component, which automatically serves optimized formats based on the browser's Accept header:
import Image from 'next/image';
<Image src="/hero.jpg" alt="Hero" width={1200} height={630} />
Next.js handles format negotiation and serves WebP when the browser supports it. See the Next.js Image documentation for configuration options.
WordPress
WordPress has supported uploading and using WebP images since version 5.8, provided the server's image library (GD or Imagick) supports it. For automatic conversion of existing images or serving WebP versions to visitors, use an image optimization plugin (ShortPixel, Imagify, EWWW Image Optimizer) or a CDN with on-the-fly format conversion.
Reference: WordPress 5.8 WebP support dev note
Static Site Generators
For Eleventy, Hugo, or Astro projects, add Sharp or cwebp as a build step:
{
"scripts": {
"build:images": "node scripts/compress-images.js",
"build": "npm run build:images && eleventy"
}
}
This ensures every image is compressed before the site is deployed.
Recommended WebP Settings by Image Type
| Image Type | Mode | Starting Quality | What to Inspect |
|---|---|---|---|
| Hero / full-width photo | Lossy | 80 | Gradient banding, blurring of fine detail |
| Product thumbnails | Lossy | 75–80 | Color accuracy, edge sharpness |
| Gallery images | Lossy | 80 | Overall tonal fidelity at 100% zoom |
| Logo with flat colors | Lossless | — | Color accuracy, anti-aliasing |
| Icon (small, sharp edges) | Lossless | — | Pixel-level edge rendering |
| Screenshot with text | Near-lossless | 60 | Text legibility, fine lines |
| Background pattern | Lossy | 70–75 | Tiling seams, texture noise |
A practical workflow: start at quality 80, check the result at 100% zoom, then lower in steps of 5 until you notice artifacts. That boundary is your optimal setting for that image type.
Common WebP Compression Mistakes
Recompressing Already-Compressed Files
Each lossy compression pass degrades quality. If you compress a WebP at quality 80, then compress the result again at quality 80, you lose more data. Always go back to the original source file (PNG, TIFF, RAW) when adjusting compression settings.
Using Quality 100 in Lossy Mode
Setting -q 100 in lossy mode produces files nearly as large as lossless but without the guarantee of pixel-perfect output. If you need zero quality loss, use -lossless instead.
Skipping the Resize Step
Even a perfectly compressed WebP wastes bandwidth if you serve a 2400-pixel image to a 375-pixel mobile screen. Use the srcset attribute or resize in your build pipeline first:
<img
srcset="hero-400.webp 400w,
hero-800.webp 800w,
hero-1200.webp 1200w"
sizes="100vw"
src="hero-1200.webp"
alt="Hero image"
loading="lazy"
/>
Ignoring the Alpha Channel
WebP supports transparency, but the alpha channel has its own quality setting (-alpha_q). The default is 100 (lossless alpha). If your image has complex transparency—such as soft shadows—lowering alpha quality can save additional bytes without visible change.
Not Adding Lazy Loading
For images below the fold, add loading="lazy" to defer downloading until the user scrolls near them. This reduces initial page weight without any compression changes.
How to Check Whether Compression Worked
After compressing, verify both file size and visual quality before publishing.
Pre-Publish Verification Checklist
- File size — Record the original and compressed sizes. Check that the reduction is meaningful given the source format and image content. There is no universal target percentage; a complex photo and a flat-color icon compress very differently.
- Dimensions — Confirm the image is sized to the largest display width it will actually render.
- Visual quality at 100% zoom — Open the original and compressed image side by side. Look for banding in gradients, blockiness in flat areas, and blurring of fine detail.
- Format fallback — If the image is critical, wrap it in a
<picture>element with a JPEG or PNG fallback. - LCP image priority — If the image is above the fold and likely your LCP resource, add
fetchpriority="high"and do not useloading="lazy". - Lazy loading for below-fold images — Add
loading="lazy"to all images below the fold. - Alt text — Ensure every image has a descriptive
altattribute. - Lighthouse / PageSpeed Insights — Run PageSpeed Insights and check that "Properly size images" and "Serve images in next-gen formats" pass.
- Search Console — After deploying, monitor the Core Web Vitals report for LCP changes.
If you need to compress a few images quickly without setting up a local tool, LessMB is a straightforward online option for WebP, JPEG, and PNG files—useful for ad-hoc optimization between code deploys. For production batch workflows, cwebp scripts or Sharp remain the more reliable choice.
WebP vs AVIF: Which Format Should You Serve First?
AVIF (AV1 Image File Format) is the newer format that compresses smaller than WebP at similar quality, but there are trade-offs:
| Factor | WebP | AVIF |
|---|---|---|
| Compression vs JPEG | Significantly smaller (Google compression study) | Typically smaller than WebP at similar quality |
| Browser support | Widely supported; check Can I Use | Good modern browser support; check Can I Use |
| Encoding speed | Fast | Significantly slower (varies by encoder and settings) |
| Decoding speed | Fast | Moderate |
| Maturity | Production-ready | Production-ready |
The practical recommendation: serve WebP as your default, and use the <picture> element to offer AVIF to browsers that support it:
<picture>
<source srcset="hero.avif" type="image/avif" />
<source srcset="hero.webp" type="image/webp" />
<img src="hero.jpg" alt="Hero image" loading="lazy" />
</picture>
This gives you the best compression where supported, with reliable fallbacks. Verify current browser support figures on Can I Use before making format policy decisions, as support percentages change over time.
FAQ
Can I compress WebP without losing quality?
Yes. Use lossless WebP mode: cwebp -lossless input.png -o output.webp or sharp('input.png').webp({ lossless: true }). Lossless WebP preserves every pixel while producing files smaller than PNG. For photographs, lossy at quality 80 is typically indistinguishable from the original at normal viewing sizes.
Can I batch-convert hundreds of images to WebP?
Yes. Use a shell loop with cwebp, a Node.js script with Sharp, or a build tool plugin. For WordPress sites, plugins like ShortPixel handle bulk conversion automatically. The Sharp batch script shown earlier in this article processes every JPEG and PNG in a directory.
Does WebP support animation?
Yes. WebP supports animation, and you can create animated WebP files with the gif2webp tool included in libwebp. Animated WebP files are typically smaller than equivalent GIFs.
Should I resize before compressing WebP?
Yes. Resize the image to the largest display size it will actually render, then encode. Serving a 2400-pixel image on a 400-pixel screen wastes bandwidth regardless of compression quality. Sharp's .resize() and cwebp's -resize flag both handle this in the same step as encoding.
What happens if a browser does not support WebP?
Every major browser released since 2020 supports WebP. If you need a safety net, use the <picture> element with a JPEG or PNG fallback as shown in the AVIF section above.
How much does WebP compression improve page load time?
It depends on how image-heavy your pages are. Because images are typically the largest resource category by byte weight, meaningful compression savings translate directly into reduced transfer time. The effect is most noticeable on image-heavy pages (homepages, product grids, galleries) and for visitors on slower connections.
Should I strip metadata from WebP files?
Yes. Removing EXIF and other metadata saves bytes per image. Sharp strips metadata by default. With cwebp, metadata is not embedded by default, so no extra step is needed.
Practical Next Steps
- Audit your current images — Run Lighthouse on your site and check the "Serve images in next-gen formats" and "Properly size images" audits. They list every image that would benefit from optimization.
- Start with your heaviest pages — Identify the pages with the largest total image weight (usually homepages and product pages) and compress those images first.
- Choose your tool — Use cwebp for one-off or scripted compression, Sharp for Node.js projects, or an online tool like Squoosh or LessMB for quick fixes.
- Set a quality baseline — Compress at quality 80, check the result at 100% zoom, and adjust. Document your optimal settings so your team can stay consistent.
- Add a format fallback — Wrap critical images in
<picture>with JPEG or PNG fallbacks for maximum compatibility. - Automate — Add WebP compression to your build pipeline so every image is optimized automatically before deployment.
References
- Google, "cwebp Encoder," developers.google.com/speed/webp/docs/cwebp
- Google, "Lossless and Transparency Encoding in WebP," developers.google.com/speed/webp/docs/webp_lossless_alpha_study
- Can I Use, "WebP image format," caniuse.com/webp
- Can I Use, "AVIF image format," caniuse.com/avif
- HTTP Archive, "Page Weight," httparchive.org
- WordPress, "WordPress 5.8 adds WebP support," make.wordpress.org/core/2021/06/07/wordpress-5-8-adds-webp-support/
- Next.js, "Image Component," nextjs.org/docs/app/api-reference/components/image
- Sharp documentation, sharp.pixelplumbing.com