This article details the architectural approach to building a robust, serverless frontend XML beautifier capable of handling multi-gigabyte files within a browser environment without memory exhaustion. It highlights the use of web standards like File Stream API, Web Workers, IndexedDB, and Service Workers to process data sequentially, offload heavy computations, and manage memory effectively by flushing to disk.
Read original on Dev.to #architectureProcessing large files (1.5GB+) directly in a web browser presents significant challenges due to RAM limitations and the synchronous nature of the main thread. Traditional approaches often lead to browser freezes or crashes as the entire file is loaded into memory. This article explores a novel, 100% frontend, serverless architecture designed to overcome these limitations by leveraging browser-native APIs for efficient, streamed processing.
The core of the solution is a sequential data processing pipeline that avoids loading the entire file into RAM. This approach breaks down the task into manageable chunks and delegates work to background threads and persistent storage.
Distributed Processing in the Browser
This architecture effectively creates a 'distributed' system within a single browser tab, using Web Workers for concurrent processing and IndexedDB for persistent storage. This pattern is valuable for any browser-based application needing to handle large datasets or compute-intensive tasks without offloading to a backend server.
// Inside processXMLStream() - Running on the Web Worker thread
while (true) {
const { done, value } = await reader.read();
if (done) break;
bytesProcessed += value.length;
// ... UI progress update ...
let text = decoder.decode(value, { stream: true });
// ... chunk processing and indentation logic ...
if (textBuffer.length > 40 * 1024 * 1024) { // Periodically dump string cache buffers into binary memory slots (~40MB spans)
const encoded = encoder.encode(textBuffer);
totalFormattedBytes += encoded.length;
outputQueue.push(encoded); // Queue for IndexedDB write
textBuffer = '';
}
}