Is `Body.json()` faster than `JSON.parse(responseText)` for JSON received from `fetch`?

Viewed 310

Is Body.json() faster than JSON.parse(responseText) for JSON received from fetch?

Theoretically Body.json() can start decoding JSON as soon as it receives the first bytes from the ReadableStream from fetch. Is this how it works? Or does it wait until all bytes are received?

const response = await fetch(url);
const json = await response.json();
const response = await fetch(url);
const text = await response.text();
const json = JSON.parse(text);

So, is there a difference between these versions of the code?

1 Answers

You are right that the body gets consumed while fetching (and that the body is a stream), but per specs, when the browser is to consume the body, it has to read all bytes from this stream with a stream reader before it can "[r]eturn the result of transforming promise by a fulfillment handler that returns the result of the package data algorithm".

This means that before Body.json() can even call its first step utf-8-decode, the full body must already have been read as an Uint8Array, and the same applies to all package data types.

Then we can conclude that

fetch( url )
  .then( body => body.json() );

is actually syntactic sugar for

fetch( url )
  .then( body => body.arrayBuffer() )
  .then( bytes => new TextDecoder().decode( bytes ) )
  .then( text => JSON.parse( text ) );

and that

fetch( url )
  .then( body => body.text() );

is itself syntactic sugar for

fetch( url )
  .then( body => body.arrayBuffer() )
  .then( bytes => new TextDecoder().decode( bytes ) )

And thus if you add yourself the .then( text => JSON.parse( text ) ), you actually have exactly the same operations being performed.

Related