My Authors
Read all threads
@tannerlinsley That’s exactly what I’m saying here. Suspense *as a feature* doesn’t do much, and is already available (it even works with caveats in stable). The point isn’t that feature but the whole picture — reading data anywhere in the tree without ceremony. That requires a cache.
@tannerlinsley When we say “Suspense for data fetching” we don’t mean “the Suspense component”. That’s been done over a year ago. We mean an integrated and flexible solution that lets you write code in that paradigm.
@tannerlinsley This solution includes: a way to read data anywhere in the tree, a consistency guarantee (if parent and child both read some data for new ID, you don’t show old+new mixed up), a cache layer to avoid waterfalls, an invalidation strategy, plus a code splitting integration.
@tannerlinsley You can’t implement parent/child consistency well without Suspense. <Parent id> and <Child id> read different data by id and id prop changes. If your solution shows a mix of old and new data while both are refetching, that’s the problem Suspense *as a paradigm* solves.
@tannerlinsley But Suspense as a paradigm also introduces new problems *because* it solves consistency (without consistency you can ignore them). Such as — if you were looking at something, and now it’s refetching, sometimes it’s bad to replace already fetched content back with a big spinner.
@tannerlinsley Now this isn’t some minor UX thing. This is a pretty major expectation for a user that the content they’re looking at doesn’t suddenly disappear. Like if you paginate with “load more” you don’t want existing items to go away.
@tannerlinsley This is why “declarative and consistent loading states” were not attempted before. You get the “blowing content away” problem and you can’t solve it without framework-level support. Concurrent Mode is a solution to that problem. Because it can render next screen “in memory”.
@tannerlinsley So I think stating spinners are a “minor thing” is misleading. If you have declarative loading states and also solve consistency then spinners become a major problem. That’s why we don’t recommend people to use Suspense for data fetching in stable releases. Without CM it sucks.
@tannerlinsley Now if we talk about Suspense+CM then it already works. Relay Hooks works and the whole new website is built on that. People can try. But not everyone is happy with Relay as a solution. So the remaining part is a cache implementation that doesn’t encourage waterfalls.
@tannerlinsley The waterfall problem is interesting. It’s a direct consequence of (1) wanting colocation and (2) wanting consistency. If Parent and Child must be consistent, Child can’t render until Parent is ready — means we don’t know there’s a nested request. This is very slow at scale.
@tannerlinsley Yes, you can get around it by manual prefetching. That also doesn’t scale. It works for a small app but it doesn’t work for hundreds or thousands of components, each of which may want to read some data. If we don’t solve that scale, it doesn’t count.
@tannerlinsley Relay has a scalable solution. It avoids waterfalls automatically by composing queries at compile time. So the root query always “knows” what children are going to want before their code even loads. But Relay isn’t for everyone. So we want to build a more generic version.
@tannerlinsley The easiest way to avoid client waterfalls is to move them to the server. Low latency. This is conceptually exactly what GraphQL does, but you don’t need GraphQL for that. It’s just a single server endpoint behind which may several different APIs for different components.
@tannerlinsley That also gives you ability to code-split based on *data*. Why load LogedOffNavbar if user is logged in? Why load GifCommentImage when the comment did not include a GIF?

If you centralize data fetching on the server then its response can include *code* chunks. Code is data.
@tannerlinsley Once you go that way you realize that some code isn’t even needed on the client. Why load Comment if it’s only ever re-rendered when we talk to the API? Why not render it as a *part* of the API response? That’s how we can drastically reduce the client bundle size.
@tannerlinsley So “Suspense” isn’t that one feature (declarative loading states). It’s *everything else* that makes that feature possible without sacrificing consistency or efficiency.

But from user’s perspective none of this matters. They just “read data” anywhere. That’s the goal.
Missing some Tweet in this thread? You can try to force a refresh.

Keep Current with Dan Abramov

Profile picture

Stay in touch and get notified when new unrolls are available from this author!

Read all threads

This Thread may be Removed Anytime!

Twitter may remove this content at anytime, convert it as a PDF, save and print for later use!

Try unrolling a thread yourself!

how to unroll video

1) Follow Thread Reader App on Twitter so you can easily mention us!

2) Go to a Twitter thread (series of Tweets by the same owner) and mention us with a keyword "unroll" @threadreaderapp unroll

You can practice here first or read more on our help page!

Follow Us on Twitter!

Did Thread Reader help you today?

Support us! We are indie developers!


This site is made by just two indie developers on a laptop doing marketing, support and development! Read more about the story.

Become a Premium Member ($3.00/month or $30.00/year) and get exclusive features!

Become Premium

Too expensive? Make a small donation by buying us coffee ($5) or help with server cost ($10)

Donate via Paypal Become our Patreon

Thank you for your support!