1/10, at 0ms.
The browser sends an HTTP GET request to the server and the request reaches the handler responsible for SSR and that invokes `react-dom/server`'s `renderToPipeableStream`.
2/10, at 50ms.
The react-dom/server then preps the app for rendering and does an initial rendering of the component tree.
At this point, react-dom/server would have identified the list of suspenses in the tree.
3/10, at 250ms.
Once the server is aware of all the suspenses, it will flush an initial HTML response to the browser with fallback contents in the place of all suspenses in the tree.
Note: The server still keeps the HTTP connection open to send more data, once it has them.
4/10, at 500ms.
The browser will process this initial response chunk and render it for the user. The page now typically has the static text and the loader(fallback contents).
At this point, the user has something to look at and is also aware that the page is still loading.
5/10, at 750ms.
While all the above was happening, the server was working on fetching data for all the suspenses in the tree.
And let's say, at this point, the first suspense in the component tree has resolved and rendered the required content.
6/10, at 760ms.
Now the server will flush another chunk of response to the same HTTP connection, with the newly resolved suspense data and some JS code to replace the already rendered fallback content on the browser with the new data.
7/10, at 800ms.
The browser gets the chunk of data, which would be something like the following(just for understanding):
8/10, at 810ms.
The browser replaces the loader on the page for the first suspense with the newly received data as a result of the inline JS script execution.
Now the user has more real content to look at.
9/10, at 1500ms.
Steps 5-8 would have got repeated for all the suspenses in the page, and the server closes the connection.
Now the user has a fully loaded page with all the suspenses resolved in a progressive manner.
10/10.
As a result of this streaming server rendering, the user was able to see some initial content at 500ms instead of waiting on a blank page till 1500ms to see the full page getting rendered at the same time.
A clear performance win while keeping together the UX. @reactjs ๐
NOTE: This thread is more like a 30,000-foot view of what is happening during a streaming SSR, for an in-depth understanding, please look at @dan_abramov's deep dive on this topic here: github.com/reactwg/react-โฆ
โข โข โข
Missing some Tweet in this thread? You can try to
force a refresh