Render as you fetch (with and without suspense)

Kent C. Dodds
Kent C. Dodds

React Suspense for Data Fetching is an experimental feature in React that opens the doors to a lot of really awesome performance improvements as well as developer experience improvements thanks to the declarative APIs given around asynchrony.

A read-through of the docs is suggested because it's interesting. One of the things that I find of particular interest in the docs is the section titled "Approach 3: Render-as-You-Fetch (using Suspense)." The arguments for this approach is the performance improvement opportunity which I tried to sum up in this tweet:

To boil it down, we're talking about what happens when the user performs an action that results in loading some code that's been code-split (like navigating to a route).

So, here's the user interaction we're going to use for our example:

User clicks "pikachu" and after a loading delay, pikachu's data and photo is displayed

So here's what most of us do (no shame, it's just natural):

  1. Load, parse, run the code and request the loading spinner assets 2. Load the data the code needs 3. Load the assets based on the data

Here's what that might look like in the network tab:

A DevTools Screenshot showing a waterfall of requests

This is what we call a "waterfall" effect. Because the lazily-loaded code is the code that requests the data, we have to wait until it's loaded before we can actually request the data and assets it needs.

In project management terms, this waterfall effect is what we call the "critical path":

In project management, a critical path is the sequence of project network > activities which add up to the longest overall duration, regardless if that > longest duration has float or not. This determines the shortest time possible > to complete the project. There can be 'total float' (unused time) within the > critical path. – > Wikipedia

But here's the important aspect of the critical path: it's all about dependencies. And successful project managers know how to reduce dependencies so we can take advantage of parallization and hopefully reduce the time it takes to complete the project.

So, in our case, what if there's a way for us to start loading the data and assets as well as the code all at the same time? Would that not speed things up? You bet it would! Check this out:

A DevTools Screenshot showing all the same requests from the previous image except they all start at the same time

Because we already have all the information we need to start pre-loading the code, data, and assets, we simply fire off those requests all at the same time.

But this begs the question: "Why do we have those dependencies in the first place? Why don't we always trigger these requests right away?" The answer is because it's easier to maintain code where the data requirements are colocated with the code that requires the data.

But in EpicReact.Dev, you'll learn how you can get the benefits of data colocation as well as pre-loading of code, data, and assets and how to do that both with "suspense for data fetching" as well as without.

Get my free 7-part email course on React!

Delivered straight to your inbox.