Back to KB
Difficulty
Intermediate
Read Time
8 min

Parsing hundreds of megabytes of JSON in milliseconds in React Native

By Codcompass TeamΒ·Β·8 min read

Bypassing the JavaScript Heap: Lazy JSON Parsing on React Native

Current Situation Analysis

Mobile applications frequently inherit legacy data contracts that ship massive JSON payloads. Whether it's a bulk configuration sync, a historical data dump, or an unoptimized third-party API, developers routinely encounter responses ranging from tens to hundreds of megabytes. The standard mental model for handling these responses assumes that JSON.parse is a lightweight, synchronous operation. This assumption holds true for kilobyte-scale payloads but collapses under the weight of megabyte-scale documents.

The fundamental misunderstanding lies in conflating syntax validation with memory allocation. When JSON.parse executes in a JavaScript runtime, it does not merely validate the structure. It walks the entire document and materializes a complete object graph. Every nested object, array, string, number, and boolean becomes a distinct JavaScript value. The engine must allocate hidden classes, property storage, array backing stores, and interned strings. For a 250 MB JSON file, this process triggers exponential heap growth. The JavaScript engine attempts to construct millions of interconnected objects, causing garbage collection cycles to stall, the UI thread to freeze, and peak memory consumption to balloon to 2–4Γ— the raw file size.

Empirical testing against the public data_250mb.json fixture demonstrates the severity of this bottleneck. On iOS, standard parsing completes only after several seconds of CPU saturation, with the JavaScript heap spiking to approximately 1.2 GB. On Android, the runtime consistently triggers an out-of-memory condition and terminates the process before parsing finishes. The failure is not caused by slow syntax parsing; it is caused by the impossibility of materializing a gigabyte-scale object graph within the constrained memory limits of a mobile device. Teams that treat large JSON as a parsing problem miss the actual constraint: the JavaScript heap cannot sustain full-tree materialization.

WOW Moment: Key Findings

The breakthrough comes from shifting the parsing boundary from the JavaScript runtime to native memory. By leveraging SIMD-accelerated C++ parsing and exposing a lazy navigation interface, the cost model changes from heap allocation to memory mapping. The document remains in native memory, and JavaScript only receives lightweight handles to specific paths.

ApproachParse Time (iOS)Parse Time (Android)Peak Memory Footprint
Standard JSON.parse~3–5 secondsOOM Crash~1.2 GB JS Heap
Native Lazy JsonView~100 ms~500 ms~400 MB Native Buffer

This comparison reveals a fundamental architectural shift. The native approach does not eliminate memory usage; it relocates it. The raw bytes and simdjson padding reside in native memory, avoiding JavaScript heap allocation entirely. Navigation operations (getValue, atPath, asString) execute targeted C++ lookups and cross the bridge only when returning small primitives or nested handles. The JavaScript runtime never sees the full object graph unless explicitly requested. This enables deterministic performance on constrained devices and transforms an impossible operation into a sub-second workflow.

Core Solution

The implementation relies on three coordinated layers: native buffer management, hybrid object bridging, and lazy traversal. Each layer addresses a specific bottleneck in the traditional parsing pipeline.

1. Native Buffer Initialization

The process begins by loading the JSON file into a padded native buffer. The simdjson library requires padding

πŸŽ‰ Mid-Year Sale β€” Unlock Full Article

Base plan from just $4.99/mo or $49/yr

Sign in to read the full article and unlock all 635+ tutorials.

Sign In / Register β€” Start Free Trial

7-day free trial Β· Cancel anytime Β· 30-day money-back