PNG Optimization Deep Dive: How PNG Compression Works and How to Shrink Your PNGs
A technical yet accessible guide to PNG compression — how DEFLATE and filtering work, comparing OxiPNG vs OptiPNG vs pngquant, lossy vs lossless techniques, and when to keep PNG versus converting to WebP.
PNG files are often larger than they need to be. A screenshot saved from your OS, an export from Figma, or a graphic from Photoshop almost always contains optimization opportunities — sometimes reducing file size by 30-70% with zero quality loss.
Understanding how PNG compression works under the hood helps you make better decisions about which tools and techniques to apply. This guide covers the internals, the tooling landscape, and the practical tradeoffs between lossless optimization, lossy reduction, and format conversion.
How PNG Compression Works
PNG compression happens in two stages: filtering and DEFLATE compression. Understanding both stages explains why different tools produce such different file sizes from the same source image.
Stage 1: Row Filtering
Before any compression happens, PNG applies a filter to each row of pixels. The filter doesn't reduce data — it transforms the data to make it more compressible by the DEFLATE algorithm that follows.
PNG defines five filter types:
| Filter | Method | Best For | |--------|--------|----------| | None (0) | Raw pixel values, no transformation | Random noise, photographs | | Sub (1) | Difference from the pixel to the left | Horizontal gradients | | Up (2) | Difference from the pixel above | Vertical gradients | | Average (3) | Difference from average of left and above | Smooth gradients | | Paeth (4) | Prediction based on left, above, and upper-left pixels | General purpose |
The key insight: each row can use a different filter. The optimal filter choice depends on the actual pixel data in that row. A row of solid color compresses best with Sub (all differences are zero). A row with a vertical gradient compresses best with Up.
Most image editors use a simple heuristic to pick filters — often just applying Paeth to every row. Dedicated PNG optimizers try multiple filter combinations to find the one that produces the smallest compressed output.
Stage 2: DEFLATE Compression
After filtering, PNG compresses the filtered data using DEFLATE — the same algorithm used by gzip and ZIP files. DEFLATE combines two techniques:
-
LZ77: Finds repeated sequences of bytes and replaces them with back-references (essentially "copy 42 bytes from 350 positions back"). Longer and more frequent repetitions produce better compression.
-
Huffman coding: Encodes frequently occurring values with shorter bit sequences. Common byte values get short codes; rare values get longer codes.
The DEFLATE compression level (1-9) controls how hard the algorithm searches for repeated sequences. Level 9 searches more thoroughly but takes longer. The difference between level 6 and level 9 is typically 1-3% file size — a modest gain for significantly more processing time.
Why Default PNG Exports Are Bloated
When Photoshop, Figma, or your OS saves a PNG, it uses a fast, general-purpose DEFLATE implementation with conservative filter choices. This is reasonable — the tool prioritizes save speed over file size. But it means there's almost always room to improve.
Common sources of bloat:
- Suboptimal filter selection: Using one filter for all rows instead of per-row optimization.
- Low DEFLATE effort: Using compression level 6 instead of exhaustive search.
- Unnecessary metadata: Color profiles (iCCP), creation timestamps (tIME), text comments (tEXt), and other ancillary chunks add bytes without affecting the image.
- Unoptimized palette: 8-bit PNG (PNG-8) with a 256-color palette might include unused palette entries.
- Wrong color type: Saving an image with no transparency as RGBA (32-bit) instead of RGB (24-bit), or saving a grayscale image as RGB.
Lossless PNG Optimization Tools
These tools reduce PNG file size without changing a single pixel. The output is visually and mathematically identical to the input.
OxiPNG
OxiPNG is a modern, multi-threaded PNG optimizer written in Rust. It's the successor to OptiPNG with significantly better performance.
What it does:
- Tries all five filter types for each row and selects the combination that compresses smallest
- Recompresses using the Zopfli DEFLATE implementation (which finds better compressions than standard zlib)
- Strips unnecessary metadata chunks
- Optimizes the color type (e.g., converting RGBA to RGB if no pixels use transparency)
- Reduces bit depth where possible (e.g., 16-bit to 8-bit if all values fit)
Typical results: 10-30% reduction on PNGs exported from design tools. On already-optimized PNGs, gains are smaller (2-5%).
Speed: Significantly faster than OptiPNG due to multithreading. Processing a typical 1000x1000 PNG takes 0.5-2 seconds depending on optimization level.
OxiPNG is the engine behind Krunkit's PNG compression — it runs as a WebAssembly module directly in the browser, applying the same Rust-based optimization without uploading your files anywhere.
OptiPNG
OptiPNG is the classic PNG optimizer, written in C. It's been the standard recommendation for years and remains widely used.
What it does:
- Similar filter optimization to OxiPNG
- Uses standard zlib DEFLATE (not Zopfli by default)
- Can reduce color type and bit depth
- Strips metadata
Typical results: 5-25% reduction. Slightly less effective than OxiPNG on average because it lacks Zopfli and is single-threaded.
Speed: Single-threaded, slower than OxiPNG for large images.
Zopfli-based Tools (ZopfliPNG)
Zopfli is Google's DEFLATE-compatible compressor that produces smaller output than standard zlib by searching more exhaustively for optimal LZ77 matches and Huffman codes. ZopfliPNG applies this to PNG files.
Typical results: 3-8% smaller than OxiPNG's standard mode, but 50-100x slower.
When to use: Only for assets that are served at very high scale (millions of requests) and change infrequently. The extreme encoding time is justified only when the bandwidth savings accumulate across massive serving volume.
Comparison: Lossless Optimizers
Test image: 1200x800 PNG screenshot, 1.82 MB original (Photoshop export)
| Tool | Output Size | Reduction | Time | |------|-------------|-----------|------| | Original (Photoshop) | 1,820 KB | — | — | | OptiPNG -o2 | 1,412 KB | 22.4% | 1.8s | | OptiPNG -o7 | 1,368 KB | 24.8% | 8.2s | | OxiPNG -o4 | 1,352 KB | 25.7% | 0.9s | | OxiPNG -o6 | 1,328 KB | 27.0% | 2.1s | | ZopfliPNG | 1,289 KB | 29.2% | 48s |
OxiPNG at optimization level 4 delivers most of the benefit in under a second. The additional gains from higher levels or Zopfli are real but diminishing.
Lossy PNG Reduction
Sometimes lossless optimization isn't enough. If you need smaller files and can accept some quality loss, lossy PNG techniques can dramatically reduce file sizes.
pngquant
pngquant converts 24/32-bit PNG images to 8-bit (256-color) PNG using a sophisticated median-cut quantization algorithm with Floyd-Steinberg dithering. Despite the color reduction, results are often visually indistinguishable from the original.
How it works:
- Analyzes the image to find the optimal 256-color palette
- Maps each pixel to the nearest palette color
- Applies dithering to simulate colors not in the palette
- Saves as PNG-8 with the optimized palette
Typical results: 60-80% file size reduction. A 1.5 MB PNG-24 might become 300-400 KB as PNG-8.
Quality considerations: pngquant works remarkably well on most web graphics — UI screenshots, illustrations, charts, and icons. It struggles with photographs and images with subtle gradients, where the 256-color limit can produce visible banding.
The quality parameter: pngquant accepts a quality range (e.g., --quality=65-80). If it can't achieve the minimum quality threshold, it will leave the image unchanged rather than produce a low-quality result. This is a useful safety net.
Test Results: Lossy vs Lossless
Test image: 1000x800 UI screenshot with text, icons, and solid colors. Original PNG-24: 1.42 MB.
| Method | Output Size | Reduction | Quality | |--------|-------------|-----------|---------| | OxiPNG (lossless) | 1.05 MB | 26% | Identical | | pngquant (q80) | 298 KB | 79% | Excellent (near-identical) | | pngquant (q60) | 215 KB | 85% | Good (slight dithering visible on zoom) |
For UI screenshots and illustrations, the jump from lossless to lossy is dramatic. That 79% reduction with pngquant at quality 80 is the kind of improvement that changes your performance budget math entirely.
When Lossy PNG Makes Sense
- UI screenshots with solid colors, text, and icons — pngquant handles these almost perfectly
- Charts and graphs with distinct color regions
- Illustrations with flat color areas
- Icons and logos at reasonable sizes (though SVG is often better for these)
When to Avoid Lossy PNG
- Photographs — use JPEG or WebP instead
- Images with subtle gradients — quantization can produce visible banding
- Medical/scientific imagery — any data loss is unacceptable
- Source files — always keep lossless originals; apply lossy compression to distribution copies
PNG vs WebP: When to Convert
A common question: should you optimize your PNGs, or just convert them to WebP?
Lossless Comparison
| Image Type | PNG (OxiPNG) | WebP Lossless | WebP Advantage | |-----------|-------------|---------------|----------------| | UI Screenshot | 1.05 MB | 682 KB | 35% smaller | | Illustration | 420 KB | 285 KB | 32% smaller | | Icon (256x256) | 18 KB | 14 KB | 22% smaller | | Photo (lossless) | 8.2 MB | 5.8 MB | 29% smaller |
WebP lossless is consistently 25-35% smaller than optimized PNG. The compression advantage comes from WebP's more advanced prediction model and entropy coding.
Lossy Comparison
| Image Type | pngquant PNG-8 | WebP Lossy (q80) | Smaller | |-----------|---------------|-------------------|---------| | UI Screenshot | 298 KB | 168 KB | WebP by 44% | | Illustration | 92 KB | 64 KB | WebP by 30% |
Lossy WebP beats lossy PNG-8 as well. WebP has more sophisticated lossy compression that isn't limited to palette-based quantization.
So Why Keep PNG at All?
Despite WebP's compression advantage, there are valid reasons to stay with PNG:
- Universal compatibility. PNG works in every browser, email client, image editor, document processor, and operating system. WebP doesn't.
- Lossless fidelity guarantee. PNG's lossless compression is well-understood and trusted. For archival or source images, PNG is the conservative choice.
- Transparency in legacy contexts. Email clients, older CMS platforms, and some mobile apps don't support WebP transparency. PNG transparency is universal.
- Simple toolchain. If your pipeline doesn't support WebP generation, optimized PNG is still a meaningful improvement over unoptimized PNG.
- Favicon and app icons. Many platforms still require PNG for favicons, app icons, and Open Graph images.
The Practical Answer
For web delivery to modern browsers: convert to WebP (or AVIF) with PNG fallback. The compression savings justify the additional format.
For universal distribution (email, documents, cross-platform): keep PNG but optimize it with OxiPNG or pngquant.
For source/archival storage: keep lossless PNG as your master format. Generate WebP/AVIF from the PNG source for web delivery.
Optimization Workflow
Here's a practical workflow for optimizing PNGs in a web project:
Step 1: Audit Current PNGs
Check your existing PNG files for easy wins:
- Are any PNGs actually photographs? Convert these to JPEG or WebP immediately — a photographic PNG can be 5-10x larger than an equivalent JPEG.
- Are any PNGs using RGBA but have no transparent pixels? Converting to RGB saves 25% of the raw data before compression.
- Are any PNGs at unnecessarily high resolution? A 3000px-wide icon displayed at 64px is wasting 99.95% of its pixels.
Step 2: Lossless Optimization
Run all PNGs through OxiPNG (or your optimizer of choice). This is always safe — zero quality loss, guaranteed.
For a quick test without installing anything, you can drag your PNGs into Krunkit's compress tool and see the optimized file size immediately in your browser.
Step 3: Evaluate Lossy Reduction
For PNGs that are still too large after lossless optimization, evaluate pngquant. Test at quality 75-85 first and visually inspect the results. Most UI graphics and illustrations look excellent at these settings.
Step 4: Consider Format Conversion
For web delivery, generate WebP versions. Keep the optimized PNG as a fallback for older browsers and non-web contexts.
Step 5: Automate
Integrate optimization into your build pipeline so it happens automatically:
# Example: optimize all PNGs in a directory
find ./public/images -name "*.png" -exec oxipng -o 4 --strip all {} \;
# Generate WebP variants
find ./public/images -name "*.png" -exec sh -c 'cwebp -q 80 "$1" -o "${1%.png}.webp"' _ {} \;
Key Takeaways
-
Default PNG exports are always suboptimal. Running any PNG through OxiPNG will save 10-30% with zero quality loss. There's no reason not to do this.
-
Lossy PNG (pngquant) is underrated. For web graphics, an 80% file size reduction with near-invisible quality loss is an excellent tradeoff that many developers overlook.
-
WebP beats PNG on compression. For web delivery, WebP is the better format. But PNG remains important for compatibility, archival, and non-web contexts.
-
The biggest gains come from fixing obvious mistakes. Wrong color type, unnecessary metadata, photographs saved as PNG, oversized dimensions — fixing these "low-hanging fruit" issues often matters more than choosing the perfect optimizer.
-
Automate your optimization. Manual optimization doesn't scale. Build it into your pipeline and every image benefits automatically.
