Processing files directly inside the browser is great for privacy, but poses challenges for performance. Here is how we optimized client-side image compression to run smoothly on low-end mobile devices without freezing the UI.
The Main Thread Bottleneck
When you resize a 10MB image using a standard <canvas> element, processing (bilinear interpolation, color space mapping, encoding to PNG/JPG) runs synchronously on the main browser thread. This causes visible frames drop, making inputs and sliders unresponsive.
Our Off-Thread Solution
We redesigned the image engine to transition heavy array conversions off the main thread:
- OffscreenCanvas API: On compatible browsers, we delegate the canvas scaling operations directly to a background Web Worker.
- Typed Array Chunking: Rather than processing raw base64 strings, we convert inputs into raw
Uint8Arraybyte arrays, passing them as transferable objects. - Chunked Processing Loop: For older mobile browsers lacking OffscreenCanvas, processing is divided into micro-tasks using
requestIdleCallback, giving the renderer time to paint.
This optimization reduced image resizing frame freezes by 90%, making batch photo conversions fast and seamless on all screens.