Made In The Browser

Browser Image Compression: How Local Image Compressors Work

Browser image compression decodes a file, draws it to canvas, resizes it, and re-encodes it as JPEG, WebP, or PNG without a server round trip.

6 min read

A screenshot of vayce image compression tool

Browser image compression works by decoding the source file, drawing the pixels to a canvas, resizing if needed, and exporting a new JPEG, WebP, or PNG file. The server does not need to touch the image for that pipeline to work.

The Image Compressor uses that local pattern: drop in JPG, PNG, or WebP files, set a max width and quality, compare the savings, then download the results.

The compression pipeline

A local image compressor follows this sequence:

  1. Read the file as a Blob or ArrayBuffer.
  2. Decode it into pixels with browser image APIs.
  3. Draw the pixels to a <canvas> or OffscreenCanvas.
  4. Resize the canvas when a max width is set.
  5. Export a new Blob with a target MIME type and quality.
  6. Create a download link for the compressed file.

That is the same broad shape behind many browser image tools. The file becomes pixels, the pixels change, and the browser encodes a new file.

Decode: file bytes become pixels

The browser cannot resize or re-encode an image until it decodes the file. APIs such as createImageBitmap() turn an image Blob into bitmap data that can be drawn.

At this stage, the browser reads enough of the file to understand the image dimensions, color data, and format. A large image can consume much more memory decoded than it does on disk because compressed file bytes expand into raw pixel data.

A 4000 x 3000 image has 12 million pixels. At 4 bytes per pixel, that is around 48 MB before any extra buffers or previews.

Resize: dimensions matter most

For web pages, reducing dimensions can save more than lowering quality. A 4000px-wide photo displayed at 1200px wastes bandwidth even if the JPEG quality is reasonable.

A max-width control changes the pixel dimensions before export:

const ratio = maxWidth / bitmap.width;
const targetWidth = maxWidth;
const targetHeight = Math.round(bitmap.height * ratio);

The canvas draws the original image into the smaller target size. The result has fewer pixels to encode, so the output file can drop sharply.

Re-encode: JPEG, WebP, and PNG behave differently

After drawing, the browser exports the canvas as a new file. With OffscreenCanvas, that can look like this:

const blob = await canvas.convertToBlob({
  type: "image/webp",
  quality: 0.82
});

JPEG and WebP use the quality value for lossy compression. Lower values reduce file size but can add blur, banding, or block artifacts.

PNG is different. Browser PNG export is lossless, so a quality slider does not work the same way. To reduce PNG size, change dimensions, reduce colors with a specialized encoder, or convert a copy to WebP when transparency can be preserved.

Workers keep the page responsive

Image compression can be heavy. Decoding several large photos and re-encoding them on the main thread can make the interface pause.

Web Workers move that work to background threads. The page can keep updating progress while the worker processes files. OffscreenCanvas lets a worker render and export canvas data without attaching a visible canvas to the DOM.

This does not make the work free. It moves the CPU cost away from the UI thread and makes large batches more tolerable.

What local compression removes

Canvas re-encoding commonly strips metadata such as EXIF camera data, GPS coordinates, and orientation tags. For web publishing, that can be acceptable. For archival photography, keep the original file.

The output may also change color handling depending on the browser and encoder path. Always compare the compressed file visually when color is critical.

Good starting settings

Use settings that match the image’s destination:

DestinationStarting point
Blog imageWebP at 0.78-0.85, max width 1200-1600px
Hero imageWebP or JPEG at 0.80-0.88, max width 1600-2200px
Product photoWebP or JPEG at 0.85+, check detail closely
Transparent graphicWebP if accepted, PNG if exact compatibility matters
Email imageJPEG, resized to the displayed width

Do not compress the same JPEG over and over. Each lossy export can add damage. Start from the best available source, export once, and keep the original.

Where browser compression stops

A browser compressor is good for preparing web assets, blog images, and batches of ordinary photos. It is not a replacement for a full image editor or a production asset pipeline.

Very large images can hit memory limits. RAW files and some proprietary formats may not decode. PNG color quantization, perceptual AVIF tuning, and metadata-preserving workflows may need specialized software.

For everyday web images, the local path is enough: resize to the size the page needs, choose the format that fits the content, compress once, and inspect the result before upload.

Read More From Our Blog

Read the blog →

Explore Our Tools

Browse all tools