Optimize images in browsers with Squoosh and WebAssembly
Start with WebP for a photo and OxiPNG for a screenshot with text. For a transparent logo, try lossless WebP and check the edges against both light and dark backgrounds. Squoosh lets you compare these choices in your browser and download a separate image for your website.
Why optimize images in the browser?
Squoosh is an open-source app from GoogleChromeLabs for manually compressing one image at a time. You can compare a photo’s texture or a screenshot’s small text while changing the encoding settings. No account is required. According to its privacy documentation, image processing happens on your device, but the app uses analytics that include before-and-after file sizes. Local image processing does not mean the page makes no network requests.
How to use the Squoosh web app
Use a current desktop browser and keep your original file. These controls were checked in Chrome 151 on Linux with ordinary 8-bit sRGB still images. This walkthrough does not cover animated images, HDR, or print-oriented CMYK files.
- Open squoosh.app while online. Drag in a local photo, screenshot, or PNG with transparency, or click the image-selection area to choose it.
- Leave the left-hand Compress menu on Original Image. In the right-hand Compress menu, choose an encoder from the table below.
- Leave Resize and Reduce palette off for the first comparison. Resizing changes dimensions, and palette reduction can discard colors independently of the encoder.
- Apply the starting settings below, then wait for encoding to finish and the output size to appear. The displayed size describes the encoded result; it is rounded, so use the saved file’s byte size for an exact comparison.
- If the offline-ready notice covers the zoom controls, choose DISMISS. Move the divider across the image. Inspect at 100% zoom, then zoom in on small text, fine textures, gradients, and transparent edges. Raise quality if the smaller candidate damages details you need.
- Choose the right-hand Download link. The left-hand download saves the original. Save the candidate under a distinct name and open that actual file before replacing a website asset.
Supported formats and optimization options
These are starting points, not quality guarantees.
| Image | Encoder | Starting settings |
|---|---|---|
| Photograph | WebP | Lossless off; Quality: 75; Effort: 4 |
| Opaque screenshot with text | OxiPNG | Effort: 2 |
| Transparent artwork | WebP | Lossless on; Slight loss: 0; Preserve transparent data on |
JPEG: Choose MozJPEG if you need a JPEG output. Start with Quality: 75 and compare the saved file with the original. JPEG cannot retain transparency, so use it for opaque images. MozJPEG is the encoder’s name, not a separate file format.
PNG: OxiPNG produces PNG. Its Effort: control changes compression work rather than image quality. It is a useful first choice for screenshots, where even small changes can blur text. A higher effort setting costs more encoding time; a smaller output is not guaranteed.
WebP: For opaque text, also compare Lossless WebP with Slight loss: 0. For transparency, turn on Preserve transparent data. That option retains hidden RGB data passed to the encoder; it cannot restore values already changed during browser decoding. The WebP settings implementation shows that increasing slight loss permits near-lossless processing even with the lossless switch on.
AVIF: Try AVIF for an opaque photograph, starting with Lossless off, Quality: 50, and Effort: 4. Compare its download with your WebP candidate. Quality scales differ between encoders: AVIF at 50 and WebP at 75 are not equivalent quality targets.
The menu also contains JPEG XL (beta). An encoder’s presence in Squoosh does not establish that your delivery browser or image viewer supports its output. Use the formats above for this walkthrough and check the downloaded image in the browsers you intend to serve.
Comparing image quality before and after optimization
“Visually acceptable” and “lossless” answer different questions. A lossy photo can look acceptable at its display size while having different decoded pixels. A lossless codec preserves the pixels it receives, but Squoosh first draws decoded images through a browser canvas. That step can change color values, especially around partial transparency. Neither OxiPNG nor the WebP lossless switch guarantees exact source RGBA preservation through the whole app.
For a screenshot, inspect thin strokes and small text. For a photo, inspect texture, gradients, color shifts, and compression artifacts. For a logo, inspect transparent edges on the background it will actually use. The preview helps you choose a candidate; inspecting its downloaded file checks that you saved the intended result. If exact pixels or original metadata are required, use a native workflow and verify those properties separately.
Check the downloaded file
Open the candidate in your target browser or image viewer. Confirm its format, dimensions, and transparency, then compare its actual byte size with the original. Keep the smaller file only if its appearance and compatibility meet your needs. An already compressed source may produce a larger candidate, and re-encoding a JPEG introduces another lossy generation.
A different compressed-file hash does not establish quality loss. Conversely, matching dimensions and a working preview do not establish pixel identity. Strict losslessness requires comparing decoded pixels with the same color and alpha interpretation, including hidden colors in fully transparent pixels; visual inspection cannot prove that equality.
Prepare an offline session
Squoosh caches app and codec assets through a service worker. Prepare in the same browser profile you will use offline:
- On your first visit, wait for Ready to work offline. While online, open a local image and finish an encoding and download with each codec you plan to use. The initial message alone does not verify that those codecs are available.
- Disconnect from the network and reload the same tab. Choose another local image, repeat the intended settings, and check the newly downloaded file. This tests a fresh load rather than a codec that is still in memory.
- If encoding or reloading fails, reconnect, reload Squoosh while online, and repeat the encoding and download. Then retest offline. Use only a codec that passes your offline check, or stay online for that conversion.
In the tested Chrome setup, WebP completed this offline reload-and-download path. OxiPNG failed after reload despite successful online preparation. Do not assume every encoder in the menu is available offline. Keep the site’s stored data; clearing it or browser cache eviction means you need to prepare and test again.
Limitations of browser-based optimization with Squoosh
The web interface handles one image at a time. Large images and high effort settings can consume substantial memory and CPU, so start with a modest image and lower effort if encoding stalls. If a codec fails, reconnect to load its assets and try another encoder. Preserve the source instead of using a partial or unverified download.
How WebAssembly enhances image optimization in Squoosh
Squoosh’s codec projects build JavaScript glue and WebAssembly modules for codecs such as MozJPEG and WebP. This lets the app run those encoders locally. You do not need to write WebAssembly or install the codec toolchains to use the interface. Encoding speed still depends on the image, settings, and device.
Alternative approaches to image optimization
For repeatable PNG processing, the native Oxipng walkthrough explains separate outputs and pixel-preservation settings. For processing uploads in an application, see Transloadit’s 🤖 /image/optimize Robot and Image Processing API.
