Skip to content

Limitations and FAQ ​

Why is it slower than canvas.toBlob? ​

Because it does more: several encodes, a decode and an SSIM computation per candidate. Typical images take 1–4 s, 12 MP photos 3–4 s (8–12 s when AVIF is allowed), a 5 MP screenshot up to ~17 s in balanced. A single canvas encode takes 5–800 ms. If latency matters more than bytes: use balanced, lower maxCandidates, use searchStrategy: "fixed", or remove avif from autoFormats. See the benchmarks.

How much memory does it use? ​

Median peak ≈ 300 MB per job in the benchmark (Node, same WASM codecs), up to ~1.1 GB for 5 MP screenshots and 12 MP photos with AVIF. WebAssembly memory never shrinks, so workers are terminated after images above 8 MP (recycleAfterPixels) and after 30 s idle. On low-memory mobile devices prefer maxWidthOrHeight and fewer formats.

Why not HEIC? ​

There is no reliable, licence-compatible decoder for the browser: libheif is LGPL and HEVC is patent-encumbered; Safari's native decoder would make results browser-dependent. HEIC files fail fast with UNSUPPORTED_FORMAT; upload them as they are or convert them on the server.

Why not JPEG XL? ​

Only Safari decodes it by default, so JXL outputs would not be displayable for most users.

Why not pngquant / lossy PNG? ​

libimagequant is GPL-3.0 (or commercial), which is incompatible with permissive redistribution.

Is the SSIM threshold "visually lossless" for everyone? ​

No. SSIM is a proxy. It is computed the same way for every candidate and validated against a reference implementation, but it under-weights banding and chroma bleeding. Tune minQuality on your own content.

Does it work in Firefox and Safari? ​

Yes. The browser suite (compression in a worker, lossless pixel equality, alpha, AVIF output, MIME sniffing, cancellation, a 12 MP image, and the CSP/no-WASM fallback) runs in CI on Chromium, Firefox and WebKit, Safari's engine. WebKit in Playwright is not identical to shipping Safari on iOS; real-device testing is still recommended. Under the canvas fallback Safari cannot encode WebP, so Optiq falls back to JPEG/PNG there and reports it.

Does anything get uploaded or logged? ​

No. The library fetches only its own JS/WASM files. Image data stays in the page until your code uploads it.