What changes are planned for Suspense in 18? · reactwg/react-18 · Discussion #47 (original) (raw)
Since most of this information is spread between other topics, I will reply with a set of links.
Changes to existing <Suspense>
behavior in React 18
Since <Suspense>
support before 18 was limited, we don't expect these changes to affect existing code. However, let's enumerate them.
- Fixing 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 re-fires 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. - on the server no longer throws: It used to be a hard error to render
<Suspense>
in a tree on the server. Now 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.
New <Suspense>
features in 18
- 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.
- and lazy on the server: You can now use
<Suspense>
andlazy
on the server. Together with the newpipeToNodeWritable
method, this solves long-standing pain points and performance problems with server rendering:- Code splitting works together with SSR. You don't have to choose one or the other.
- React uses your
<Suspense>
boundaries to stream the page HTML in visual chunks. - React uses your
<Suspense>
boundaries to hydrate the page in chunks, improving responsiveness.
Features that may or may not appear in 18.0
- "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. <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 facebook/react#19936.- Reducing jank: At some point we'll want to take another look at adjusting the small details to reduce visual jank to the minimum. For example, the automated throttling described above currently only works for revealing "next level" of content, but doesn't work for sibling
<Suspense>
boundaries that reveal with a short period of time between them yet.
Likely after React 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, but 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.
- Built-in Suspense 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.) - 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.
- Clear documentation and recommendations for data fetching library authors on how to integrate with Suspense.