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:
- Read the file as a
BloborArrayBuffer. - Decode it into pixels with browser image APIs.
- Draw the pixels to a
<canvas>orOffscreenCanvas. - Resize the canvas when a max width is set.
- Export a new
Blobwith a target MIME type and quality. - 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:
| Destination | Starting point |
|---|---|
| Blog image | WebP at 0.78-0.85, max width 1200-1600px |
| Hero image | WebP or JPEG at 0.80-0.88, max width 1600-2200px |
| Product photo | WebP or JPEG at 0.85+, check detail closely |
| Transparent graphic | WebP if accepted, PNG if exact compatibility matters |
| Email image | JPEG, 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.





