Progressive JSON
Based on The PrimeTime's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.
Conventional JSON delivery blocks client work because parsing requires the full payload, so any slow subtree delays everything.
Briefing
Progressive JSON aims to make JSON delivery behave more like progressive images: start with a rough, usable shape and refine it as more data arrives—so clients don’t have to wait for an entire JSON payload before doing anything. The core complaint driving the idea is straightforward: with conventional JSON over the wire, parsing can’t happen until the closing brace arrives, which means the client stays idle while the server finishes every dependency (often including slow database work like “comments”). That “all-or-nothing” behavior is treated as normal engineering practice even though it blocks user work whenever any part of the payload is slow.
A streaming-JSON approach tries to fix this by parsing incomplete input and emitting partial object trees as keys and subtrees become available. But the transcript highlights a major drawback: streamed objects are inherently incomplete and therefore “malformed” relative to the types the application expects. A top-level object might be missing its footer because it hasn’t arrived yet; a post’s comments might be truncated without any reliable way to know whether more comments are coming. In practice, application logic usually assumes fields are present and complete, so streaming forces developers into pervasive conditional checks and awkward “ready/complete” signaling.
The discussion then pivots to a more structured alternative: send the data “breadth first” so the client can reconstruct the overall tree shape early, while unresolved parts are represented as placeholders (the transcript uses promises as the mental model). This reduces the need to box values into “undefined” states, but it still shifts complexity to the client: code must handle properties that may be promises rather than concrete values, and type systems become awkward if fields can be either a value or a promise. The transcript also raises practical concerns—custom encoding formats can complicate debugging and require bespoke parsers, and it’s not obvious that this approach reduces total work compared with streaming.
As the conversation deepens, it connects these ideas to real systems that already do something similar. React Server Components are presented as a concrete example of streaming a component tree as progressive JavaScript/props, where the client reconstructs UI incrementally as server data resolves. Crucially, React doesn’t necessarily “show holes” when data is pending; instead, it uses Suspense to control what the user sees while data continues arriving. That decouples data arrival order from UI reveal order: the server can stream as fast as it can, while the UI transitions only at intentionally designed loading boundaries.
The transcript ends with a challenge: streaming alone isn’t enough. The programming model must let clients do useful work with incomplete information, and it must handle slow parts without forcing the rest of the page to wait. React’s Suspense-based approach is framed as a key piece of that solution, turning progressive data delivery into progressive, user-friendly rendering rather than a brittle tangle of conditional logic.
Cornell Notes
Progressive JSON borrows the “progressive image” idea: deliver a usable approximation of a JSON structure early, then refine it as more data arrives. Straight streaming JSON runs into a type/shape problem—partial objects are incomplete, so application logic that expects fully formed types must constantly check what’s missing. A proposed workaround is to send the tree breadth-first and represent not-yet-available subtrees with placeholders (promises), letting the client reconstruct the overall shape while waiting on specific parts. React Server Components are cited as a production-grade example of streaming a component tree, with Suspense controlling what the user actually sees while data continues to load. The takeaway: streaming requires a matching programming model to handle incomplete information gracefully.
Why does conventional JSON delivery force the client to wait before it can do anything?
What breaks when streaming JSON produces partial object trees?
How does breadth-first streaming with placeholders (promises) change the problem?
Why does the transcript connect these ideas to React Server Components and Suspense?
What’s the key warning about “streaming alone”?
Review Questions
- What specific failure mode arises when streaming JSON yields incomplete objects relative to expected types?
- Compare depth-first streaming and breadth-first streaming: what changes about when the client can reconstruct the overall structure?
- How does Suspense address the user-experience problem that raw streaming would otherwise create?
Key Points
- 1
Conventional JSON delivery blocks client work because parsing requires the full payload, so any slow subtree delays everything.
- 2
Streaming JSON can emit partial structures, but partial objects often violate the types and completeness assumptions most app logic relies on.
- 3
Breadth-first delivery with placeholders (promises) can preserve the overall tree shape early, but it shifts complexity to the client’s handling of unresolved fields.
- 4
Custom encoding/placeholder schemes may require bespoke parsing and complicate debugging, potentially offsetting performance gains.
- 5
React Server Components demonstrate a practical version of progressive tree streaming, where the client reconstructs UI as server data resolves.
- 6
Suspense is presented as the mechanism that prevents users from seeing arbitrary gaps, aligning progressive data arrival with intentional loading states.