Dev.to WebDev 🛠 Dev 👁 1 📖 2 min read

Browser-local image compression: target feedback without pretending to guarantee the byte size

An upload limit such as “1 MB maximum” sounds like one problem, but it is really two: the image may contain more pixels than the destination needs, and its encoding may spend more bytes than the visible quality requires.

Browser-local image compression: target feedback without pretending to guarantee the byte size

An upload limit such as “1 MB maximum” sounds like one problem, but it is really
two: the image may contain more pixels than the destination needs, and its
encoding may spend more bytes than the visible quality requires.

The safest order is usually:

  1. Choose the largest display width the destination actually needs.
  2. Encode at a reasonable quality.
  3. Measure the resulting bytes.
  4. Lower width or quality only if the result is still over the limit.

That last measurement matters. A browser tool cannot honestly promise that one
quality value will produce the same file size for every image. A flat
illustration, a screenshot with text, and a noisy camera photo compress very
differently.

For our small browser tool, the local flow is deliberately simple. FileReader
loads the selected file, an Image provides its dimensions, a canvas applies
the maximum width, and canvas.toBlob(..., "image/jpeg", quality) creates the
output. The app then compares blob.size with targetKilobytes * 1024 and says
whether the result is under or above the target. It does not send the source
image to our server for compression and it does not loop silently until the
picture looks bad.

Image compressor demo showing a 66.1 KB source reduced to an 18 KB JPEG, 73% saved and under the 20 KB target

In the attached demonstration, a repository-owned 66.1 KB image became an 18 KB
JPEG after limiting it to 800 px and using 35% quality. That met the selected
20 KB target, but it is only a reproducible example—not a claim that every file
will shrink by 73%.

There are important tradeoffs:

  • JPEG output does not preserve PNG transparency.
  • Small text and UI screenshots can show artifacts before photos do.
  • Exported files may not preserve all source metadata.
  • A target is feedback, not a guarantee; preview the result and keep the source.

If you want to inspect the workflow, the
browser-local image compressor
is live. The companion
1 MB walkthrough
uses 1024 KB as the target and explains why reducing dimensions should usually
come before aggressively lowering quality.

Implementation references: MDN's FileReader
and HTMLCanvasElement.toBlob().

Disclosure: ZeroGameStudio built the linked tool. This draft was prepared with
AI assistance and checked against the production implementation; the maker will
review and edit it before publication.

📰 Read the original article on Dev.to WebDev

Originally published by Dev.to WebDev. Aggregated on AIWithGhost for educational purposes — full credit and traffic to the original publisher.