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 fire
useLayoutEffect
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.
- New Streaming Suspense Server Renderer:
- 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.
- Technical preview of Server Components:
- 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. - Add
onRecoverableError
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
- Initial implementation as
-
<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
- Initial implementation as
- An API to prioritize hydrating a particular DOM element's parent tree.
- Implement as
ReactDOM. unstable_scheduleHydration
- Pick a name
- Implement as
- 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