cd /news/developer-tools/building-a-browser-only-image-compre… · home › topics › developer-tools › article
[ARTICLE · art-169944] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=↑ positive

Building a Browser-Only Image Compressor: What We Actually Measured

A developer built a browser-only image compressor that runs WebAssembly encoders and Canvas pixel work entirely inside the tab, so files never leave the user's machine. Benchmarks across five representative inputs showed gains depend heavily on the chosen route: palette quantization cut a 1920x1080 UI screenshot by 70.3% while lossless saved only 2.2%, and a small transparent icon actually grew when routed to WebP. The writeup notes large images are limited by device memory and that batching remains the weak point without a server-side API.

by read3 min views3 publishedNov 15, 2026

Building a Browser-Only Image Compressor: What We Actually Measured

Most "online image compressor" pages upload your file, compress it on a server, and hand back a download link. That works, but it costs you two things: your file leaves your machine, and the result depends on someone else's queue depth.

We wanted the opposite: the pixels never leave the browser. Here is what that looks like in practice, and what the measurements actually say.

Why "local" is an architecture decision, not a promise

A privacy claim is only as good as its architecture. If a page uploads your image, "we delete it in 24 hours" is policy. If a page never uploads, there is nothing to delete.

The verification is trivial: open the page, disconnect the network, drop an image in, and see whether a result comes out. If it does, the work happened in the tab.

What runs inside the tab

Encoding is handled by WebAssembly builds of established encoders, and pixel work runs on Canvas:

No model inference, no cloud GPU, no heuristics learned from data. Same input, same parameters, same output, every time.

The measurement table

Five representative inputs, all processed with the same build:

Input | Original | Lossless | Quantized | WebP

Transparent PNG icon 800x600 | 5.3 KB | 4.3 KB (-18.6%) | 3.3 KB (-37.6%) | 6.1 KB (larger)

Camera JPEG 2000x1500 q95 | 1.54 MB | - | q75: 374 KB (-76.2%) | -

UI screenshot 1920x1080 | 9.6 KB | 9.3 KB (-2.2%) | 2.8 KB (-70.3%) | -

Full-color PNG 1600x1200 | 473.7 KB | 375.5 KB (-20.7%) | 55.8 KB (-88.2%) | 16.1 KB (-96.6%)

GIF 400x400, 12 frames | 21.8 KB | - | 92.4 KB (larger) | 61.8 KB (larger)

Three conclusions worth keeping

The gain depends on the route, not the tool. A transparent 5 KB icon can get bigger if you route it to WebP, because the container overhead eats the savings. The same icon quantized saves 37%.

Screenshots belong on the quantized route. Lossless optimization on a 1920x1080 UI capture saves 2%; palette quantization saves 70% with no visible difference at 100% zoom.

Format flexibility is worth more than encoder tuning. Allowing WebP on full-color art took the result from 55.8 KB to 16.1 KB. Users who insist on "keep PNG" cut their own ceiling in half.

Where it breaks

Large images are limited by the device, not the code. A 4000x3000 photo takes 3-5 seconds on a low-end phone and under a second on a desktop. Peak memory is roughly concurrency × decoded bitmap × 2, so a four-way batch on 48 MB bitmaps can approach 400 MB and trigger GC churn.

Batching is the real weak point. Without a server there is no API, so bulk work means dragging files by hand. If you need an unattended pipeline, use command-line tools (oxipng, jpegoptim, ImageMagick) or a service with an endpoint. Browser-local is for a handful of files at a time.

What we'd optimize next

Downscale before encoding. Worker pools with OffscreenCanvas. Concurrency at half the physical core count. And a three-stage progress indicator (decode, encode, package) — because past about twenty files the bottleneck stops being CPU and becomes feedback.

Measurements above come from our own runs on the same algorithm family, and are meant as an upper-bound reference for what each route can achieve in a browser — not a guarantee for every input. If you want to check them, open the tool, disconnect, and run your own images.

The broader point is simple: for a specific, bounded class of tasks, the browser is now a legitimate compute target. The constraint is not whether it can run — it is whether you are willing to design for the device you do not control.

── more in #developer-tools 4 stories · sorted by recency
── more on @webassembly 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/building-a-browser-o…] indexed:0 read:3min 2026-11-15 · —