Handling 500+ Professional RAW Images in the Browser Without Melting RAM

In modern PropTech and high-end real estate marketing platforms like EpicListing, visual fidelity is everything. Professional real estate photographers do not capture properties on smartphones; they use high-end DSLR cameras that produce massive, uncompressed RAW, TIFF, and HEIC files.
When we were tasked with building a web-based portal to allow photographers to upload hundreds of these images simultaneously, we ran into a massive web-platform bottleneck: the browser memory crash.
If you let a user select 500 high-resolution photos, a standard browser tab will freeze or crash instantly. Standard image tags cannot render RAW or TIFF formats natively, and loading raw buffers of dozens of 20-megapixel images easily exceeds 1.6GB of RAM.
Here is how our engineering team designed a memory-safe, client-side thumbnail pipeline that handles 500+ professional images on a flat 25MB memory footprint—all executed purely on the user's browser with zero server-side processing overhead.
The Architecture of a Browser Crash
To understand why traditional web uploads fail with professional photography, you have to look at how browsers handle memory.
A 20-megapixel RAW image is highly compressed on disk (perhaps 20MB to 40MB). However, the moment a browser attempts to render an image, it must fully decompress it into an uncompressed RGBA bitmap in memory.
Memory Allocation=20,000,000 pixels×4 bytes (RGBA)≈80 MB of raw RAM
If a photographer attempts to preview just 20 of these images concurrently, the browser must allocate 1.6GB of RAM just to hold the pixels. Scale that to 100 or 500 images, and the operating system's Out-Of-Memory (OOM) killer will instantly terminate the browser tab.
The Lazy-Loading Paradox
When faced with a rendering bottleneck, the standard frontend reflex is to implement lazy loading—only decoding and rendering images when they enter the viewport, and releasing them when they scroll out.
However, for a heavy-duty upload manager processing non-standard formats (RAW, TIFF, HEIC), lazy loading is actually a performance trap.
- The Problem: Because the browser cannot natively render these formats, we have to run custom client-side JavaScript decoders.
- The Cost: If we decode on-demand as the user scrolls, the CPU has to continuously run heavy decoding algorithms (like
heic2anyor WebAssembly compiled decoders). This creates severe scrolling lag, UI stutters, and high battery drain.
We needed a pipeline that would execute the heavy decoding exactly once, store a featherweight, web-friendly preview, and discard the heavy bitmap buffers immediately.
The Solution: A Zero-Allocation Client-Side Pipeline
Our team designed a client-side ingestion pipeline that intercept raw file selections, decodes them under a strict concurrency guard, downsamples them in-memory, and immediately flushes the heavy original buffers.

Here is how the pipeline works step-by-step:
1. Maintaining "Cold" File References
When the user drags and drops 500 images, the browser creates a native File list. Rather than loading these files into memory, our system keeps them "cold". We store only the lightweight File object references, which act as pointers to the physical files on the user's hard drive.
2. The Viewport-Priority Queue and Concurrency Semaphore
Instead of processing all files simultaneously, we route them through a priority queue:
- Viewport Priority: An
IntersectionObservertracks which image cards are currently visible on the screen. The files corresponding to these visible cards are pushed to the front of the queue. - The Concurrency Semaphore: We implement a semaphore that limits active decoding tasks to exactly 20 concurrent workers. This ensures that we never overwhelm the browser's JavaScript thread or trigger parallel memory allocations.
3. Custom Decoders and DCT Subsampling
For non-standard formats, we load lightweight decoders dynamically: dcraw (compiled to WebAssembly) for camera RAW files, custom TIFF parsers, and heic2any for iOS HEIC files.
Crucially, we do not decode the images to their full resolution. We utilize Discrete Cosine Transform (DCT) subsampling during the decoding phase. By configuring the decoders to extract only the low-frequency coefficients, we reconstruct a low-resolution thumbnail (400px width) directly from the raw file stream. The browser never allocates a full-resolution 80MB buffer in memory.
4. Immediate Bitmap Flush and Compact Cache
Once the 400px thumbnail is drawn onto an off-screen <canvas>, we immediately convert it into a highly compressed JPEG base64 string (averaging just 50KB per image).
We then explicitly delete the canvas context, clean up the decoder variables, and let the browser's Garbage Collector reclaim the workspace memory immediately.
The Result: Pure Desktop Performance in a Web Browser
By decoupling the display thumbnail from the original raw file, we achieved incredible results on production environments:
- Flat Memory Footprint: Previewing 500 massive, professional-grade images consumes a stable, continuous 25MB of RAM. Photographers can scroll smoothly through hundreds of photos without a single frame drop or tab freeze.
- Pristine Original Uploads: Because the UI thumbnails are only for rendering, the original local
Fileobjects remain untouched on disk. When the user clicks "Upload", our system reads directly from the original local references to stream the uncompressed, raw files straight to AWS S3. - Zero Server Costs: Traditional architectures generate thumbnails by uploading files to a server and running image-processing workers (like ImageMagick). By offloading 100% of the decoding and resizing workloads to the client's browser, we saved our client thousands of dollars in monthly cloud compute bills.
Turn Complex Client-Side Challenges Into Smooth User Experiences
This project is a perfect illustration of our engineering philosophy at NUS Technology: Clarity in Strategy. Excellence in Execution.
We do not just build simple interfaces; we understand the underlying engines of the platforms we build on. Whether it involves building complex canvas editors, managing memory footprints in low-spec devices, or integrating real-time IoT hardware, we design solutions that are resilient, performant, and cost-efficient.
If your enterprise platform is struggling to scale, suffering from performance freezes, or incurring high cloud processing costs, you need an engineering partner that can optimize your software at the architectural level.
Schedule a Strategy Session with NUS Technology today to discuss how we can build a high-performance operational backbone for your business.


