Open
Description
Let's use this issue to track the remaining tasks for releasing Suspense to open source.
Last updated: March 24, 2022
Blog post: The Plan for React 18
Completed: React 16
- Release
<Suspense>
withReact.lazy
for client-side lazy loading
Completed: React 18 Alpha
- Implement concurrent rendering, which is a prerequisite to everything else.Fix fundamental flaws in the concurrency model that made the behavior difficult to understand and caused many bugs.Rewrite how React traverses the tree to unblock fixing Suspense quirks.Redesign how React integrates with the scheduler to simplify the model, fix bugs, and prepare for native browser scheduling.Fix
<Suspense>
quirks: Previously, effects would fire inside a suspended tree too early. For example, you would see an effect from a component that's still hidden behind a placeholder. Now effects will run only after the content has been revealed. We expect this to fix existing application code bugs.Hiding and showing existing content should re-fire layout effects: If a component that's already visible suspends, we show a placeholder, and later show it again. However, there was no way for the component to know that it was hidden or shown. For example, a tooltip component measuring its screen position would get incorrect measurements while it's hidden. Now we fireuseLayoutEffect
cleanup (same ascomponentWillUnmount
) on "hide", anduseLayoutEffect
setup (same ascomponentDidMount
) on "show". We expect this to fix existing application and library code bugs.<Suspense>
on the server no longer throws: It used to be a hard error to render<Suspense>
in a tree on the server. Now, for the old server renderer, it silently emits the fallback (and lets the client try to render the content instead). This shouldn't affect existing apps because previously it was not possible to render<Suspense>
on the server at all.startTransition
lets you avoid hiding existing content even if it suspends again. This is useful to implement the "show old data while refetching" pattern with minimal code.Built-in throttling of Suspense reveals: To avoid updating the screen too often and causing visual jank, React "waits" a little bit before revealing the next level of spinners — in case even more content is available by that time. In other words, revealing nested Suspense fallbacks is automatically throttled by React.- Initial streaming renderer implementation.
React.lazy
works with SSR out of the box.- Streaming HTML: React uses your
<Suspense>
boundaries to stream the page HTML in visual chunks. - Selective Hydration: React uses your
<Suspense>
boundaries to hydrate the page in chunks, improving responsiveness.- React prioritizes hydrating the part of the page you are interacting with.
- React keeps the browser responsive during hydration of
<Suspense>
boundaries. - React captures and replays missed events after hydration.
- Implement the server with support for suspending.
- Prototype a caching layer.
- Prototype React I/O libraries like
react-fetch
andreact-pg
. - Support lazy-loaded elements for server trees.
Completed: React 18
- Finalize New Streaming Suspense Server Renderer:
- Make it pass all of our existing tests.
- Prove it out in production (currently we use a hack in its place).
- Add the missing "static markup" APIs for things like emails.
- Fix known bugs with hydrating Suspense.
- Move the new server renderer from
react-dom/unstable-fizz
toreact-dom/server
.
Fall back to client rendering from closest<Suspense>
on mismatches instead of patching up the tree.AddonRecoverableError
to gather production reports about SSR mismatches.
Features that may or may not appear in 18.x
<SuspenseList>
lets you declaratively coordinate the order in which<Suspense>
nodes inside will reveal.- Implementation.
- Server support
- Finalize and document the API.
"Backup"<Suspense>
boundaries (not final naming): A way to specify that you'd like React to ignore this boundary during initial render (as if it's not there), unless React is forced to hide existing content. We sometimes call these "ugly spinners" or "last resort spinners". This use case might seem a bit exotic but we've needed it quite a few times.- Initial implementation as
unstable_avoidThisFallback
- Server support
- Pick a good name
<Suspense>
for CPU-bound trees (not final naming): A way to tell React to immediately show a placeholder without even trying to render the content. This is useful if you have an expensive tree inside. This use case is unrelated to network — it's about showing a spinner for some tree that takes a while to render. See Suspense for CPU-bound trees #19936.- Initial implementation as
unstable_expectedLoadTime
- Adjust the heuristics
- Server support
- Pick a good name
An API to prioritize hydrating a particular DOM element's parent tree.- Implement as
ReactDOM. unstable_scheduleHydration
- Pick a name
Reducing jank: Take another look at adjusting the small details to reduce any visual jank to the minimum. For example, throttle reveal of Suspense boundaries between siblings as well.
React 18.x (post-18.0): Suspense for Data Fetching
All of the above changes are foundational architectural improvements to <Suspense>
. They fill the gaps in the mechanism and make it deeply integrated with all parts of React (client and server). However, they don't prescribe a particular data fetching strategy. That will likely come after the 18.0 release, and we're hoping that to have something during the next 18.x minor releases.
This work will include:
- React I/O libraries like
react-fetch
, which is a lightweight and easiest way to fetch data with Suspense.- Initial implementation
- Finalize the API
Built-in Suspense<Cache>
which will likely be the primary recommended way for third-party data fetching libraries to integrate with Suspense. (For example,react-fetch
uses it internally.)- Initial implementation
- Try it in production
- Investigate what's missing
- Figure out the recommended strategy for normalized caches
Server Components, which will be the recommended way to fetch data with Suspense in a way that scales great and integrates with React Fetch as well as third-party libraries.- Initial implementation
- Basic Server Context implementation
- Server Context features for refetching
- Figure out the layering between Server Components and New SSR
- (This section has many follow-up questions, so it's incomplete)
Clear documentation and recommendations for data fetching library authors on how to integrate with Suspense
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
aweary commentedon Jul 13, 2018
Isn't this already exposed?
acdlite commentedon Jul 13, 2018
I meant remove the
unstable_
thoamsy commentedon Jul 15, 2018
I am looking forward to open source of the unnamed code-splitting library 💯
ryota-murakami commentedon Jul 23, 2018
What does it mean [Umbrella]?🤔☂️
ghoullier commentedon Jul 23, 2018
This mean, it's a feature which impact several projects/packages/tools.
ryota-murakami commentedon Jul 23, 2018
@ghoullier I see, Thank you so much!
JedWatson commentedon Jul 24, 2018
Hey @acdlite, just a question about how to best prepare for this. Not asking for / expecting any kind of timeline, but wondering:
Are you currently expecting these features to drop into React 16 and be easy to adopt incrementally, like the new Context API that landed with 16.3?
Or are you thinking it'll be something that pushes React to v17 and require more work to adopt?
Asking because I'm working on a roadmap that crosses over significantly with pretty much everything on your list and am trying to work out how to best deal with that.
Also do you have any tips on how to best prepare (in terms of code written today, that wants to be future compatible with these improvements to React) - polyfills / techniques / etc?
(apologies if these questions are answered elsewhere and I've missed them)
donaldpipowitch commentedon Jul 24, 2018
Adding another question to @JedWatson's questions:
16.4.0-alpha.0911da3
from February.)Thank you! ❤️
NE-SmallTown commentedon Jul 24, 2018
IMO, they will provide a blog post like before before it's been landed.
And I think you don't need to prepare too much because there is no breaking change(it does have many features that maybe would seems different/conflict with current practices, like redux fetch with suspense, but there will be a codemod or easy encapsulation to do this, you know, fb has 3W+ components). And if you watch the talk of @acdlite (about ssr suspense in ZEIT) and @gaearon (about client suspense in iceland), you will know you don't need to worry about too much and it's not invasive.
By the way, you can just search the key 'Umbrella' in the repo and you will find more info like #8830 and #12152
IIRC, this is a misoperation?
sebinsua commentedon Jul 24, 2018
@JedWatson This comment helped me understand what a developer must do to help ensure that their application's are async safe.
cyan33 commentedon Jul 24, 2018
I'm working on rolling out the suspense module and new APIs in facebook. In case @acdlite is busy with something else, I'd like to share some of my thoughts of our experience in facebook and answer some questions of @JedWatson.
I'm not sure if it will come with React 16 or 17. According to the React team, it's likely to be released before the end of this year, which depends on how well it runs in facebook and how the related API is ready or not. But code-wise, I'm happy to say that it would be easy to adopt, because we've been experimenting for quite a while in facebook. The suspense feature will still work for the existing codebase. But with additional changes (like async rendering), you'll have more bonus that the new feature will bring you.
I'd say the migration is rather incremental and progressive. Like @NE-SmallTown said, we don't want to introduce any breaking changes. That would also be painful to roll out to facebook because we have a so large codebase. But so far, the roll out has been smooth and doesn't require you to do additional changes.
acdlite commentedon Jul 24, 2018
@JedWatson
Incrementally. Always incrementally :) Otherwise there's no way we'd be able to ship this at Facebook.
Here's what I'm expecting:
<AsyncMode>
*In sync mode,
delayMs
is always0
. Placeholders show up immediately.Suspense will work without any changes to your existing components. At one point we thought we might require
<StrictMode>
compatibility, but during our internal testing we discovered one of the best ways to upgrade to strict mode was to use Suspense. Chicken-egg dilemma. So we found a way to make it work even outside of strict mode.So the idea is that users will start migrating to Suspense even before they're ready to migrate to asynchronous rendering. Then once a subtree is ready, they can opt-in by wrapping in
<AsyncMode>
.For new apps, though, the story is different: go async by default. We'll introduce a new root API (a replacement for
ReactDOM.render
) that is async only.There will be an awkward period after the initial release where many third-party frameworks (Redux, Apollo, React Router...) may not work properly in async mode. That might hurt adoption for a while. But the idea is that the new features will be so compelling that it won't take long for libraries to either adapt or be superseded by an async-compatible alternative.
Wrap everything in
<StrictMode>
and make sure there are no warnings. We'll have more detailed migration guides as we get closer to release.hwillson commentedon Jul 25, 2018
Apollo doesn't do awkward - we'll be ready! 🕺😳
Seriously though, we ❤️ all things React, so making sure we're in-line with these changes for the initial release is not only a high priority, but it's also something we're super excited about! Thanks for all of your amazing work on this @acdlite!
markerikson commentedon Jul 25, 2018
I'll chime in and say that the Redux team is working on async compat for React-Redux.
I laid out a potential roadmap at reduxjs/react-redux#950 . TL;DR:
<StrictMode>
with no warnings (current PR: Fix getDerivedStateFromProps usage reduxjs/react-redux#980 )<Provider>
andconnect()
). We'll see how well that works with async rendering, and figure out the best path forward. (My prior proof-of-concept PR is at React 16 experiment: rewrite React-Redux to use new context API reduxjs/react-redux#898 , but we'll probably redo it based on other lessons learned from the 5.1 work.) It's likely that this release would require React 16.5 as a minimum, due to the need for new context and probably also the as-yet unreleased "read context from lifecycle methods" PR that was just merged.We'd appreciate more eyes on our WIP, and hopefully people can give us some more feedback and discussion on how they're looking at using Redux with React Suspense and async rendering so we can make sure use cases get covered properly. We're also hoping to have some more discussions with the React team about exactly what constraints we need to work with, and it'd be helpful if we could get some sample apps that would let us see what problems we need to solve for all this to work correctly.
anymost commentedon Jul 26, 2018
looking forward to the release of Async rendering and Suspense
137 remaining items