The path through the browser
- The main thread accepts a PNG or JPEG from drop, file picker, or clipboard paste.
- A module Web Worker receives the file bytes, MIME type, filename, resize percentage, and WebP choice.
createImageBitmapdecodes the source;OffscreenCanvasproduces RGBA pixel data.- The worker selects the PNG, JPEG, or WebP encoder path.
- The main thread receives a local output buffer, renders the result, and prepares downloads.
The worker boundary keeps codec work away from the interface thread. Adding files, toggling options, and reading progress remain responsive while an encoder is busy.
PNG: palette reduction, then lossless optimisation
PNG follows a two-stage path. Libimagequant first reduces the colour palette with a minimum quality of 65, target quality of 80, and speed setting 4. The resulting PNG then passes through oxipng at optimisation level 2 with alpha optimisation enabled.
If libimagequant cannot satisfy the quality floor, Squeezr skips palette reduction. The source PNG receives the lossless oxipng pass instead. When resizing is enabled, the resized pixels are encoded to PNG before that fallback because the original bytes have the wrong dimensions.
JPEG: MozJPEG at a fixed quality
JPEG and JPG input uses the MozJPEG encoder at quality 80. There is no automatic per-file quality search and no visible quality slider. That fixed contract keeps the workflow predictable: add a photograph, encode it once, inspect it, and keep the source if the delivery copy is not suitable.
WebP: an explicit format change
When WebP is enabled, either PNG or JPEG pixel data goes to the libwebp encoder at
quality 80. The output extension changes to .webp. This is the only standard path
that changes the image format, and the interface makes that choice visible before
compression begins.
Resize happens before encoding
Resize scales both dimensions by the selected percentage, preserves aspect ratio, and never upscales. The worker uses high-quality canvas smoothing before the encoder sees the pixels. A resize is treated as an explicit output request, so the resized file is returned even if its byte count happens to exceed the source.
The keep-original safeguard
With resize off, the worker compares encoded and original byte lengths. If the new output is not smaller, it returns the original bytes and filename. This avoids offering a larger file as a successful compression result.
Memory and batch limits
The main thread sends one file at a time and waits for the worker’s result before advancing the queue. That sequential design limits peak codec memory. Source images above 40 megapixels are rejected, and a batch can contain up to 20 supported files.
Codec modules are imported on first use and then reused. Thumbnails are separately bounded to a maximum 400-pixel side so the result list does not keep full-size decoded images for every item.
Verified project results
- Flat UI PNG, 900×600
- 35 KB → 3.0 KB
- 91% smaller
- Gradient-and-noise PNG, 700×500
- 753 KB → 173 KB
- 77% smaller
- Photographic JPEG
- 178 KB → 58 KB
- 68% smaller
- Gradient PNG to WebP
- Quality 80
- 99% smaller
These values come from the project’s browser fixtures. They describe those inputs, not every image. Compression ratio depends on dimensions, palette, noise, existing optimisation, transparency, and the source encoder.
What the pipeline does not promise
- Animated GIF, animated PNG, HEIC, SVG, AVIF, and RAW formats are not accepted.
- Unusual colour profiles and exotic metadata are not an archival target.
- Visual equivalence is subjective; the preview is part of the workflow.
- The tool is experimental and should not replace the only copy of an important file.
Ready to try a specific path? Open the PNG compressor, JPEG compressor, or WebP converter.