Concurrent Rendering

Sometimes, you're rendering so many components or those components are doing such complex things that you can't afford to render them all quickly enough.
The human eye perceives things at around 60 frames per second. That means a single frame is around 16 milliseconds. So if your JavaScript is taking longer than 16ms to render, the browser won't be able to keep up and your users will have a janky experience.
Unfortunately, sometimes you really just do have enough work to do that you can't keep within that budget. There are certainly things React could do to speed things up and it's constantly working on that. One innovation React came up with to help with this is called "concurrent rendering."
If you'd like to understand concurrent rendering at a conceptual level, I suggest you check out the React v18 release announcement, watch Dan Abramov's Talk at JSConf Iceland, or watch the React 18 Keynote.
Here's the basic idea: instead of rendering everything all at once, React can break up the work into smaller chunks. When the rendering is taking longer than a threshold React manages, it will pause its work and let the browser do whatever work it needs to do. Then when React gets a turn, it'll continue the work it was doing. Continously iterating toward finishing its work before finally updating the DOM with the updates of all that work.
In this way, React can keep the browser responsive and the user experience smooth even when it's doing a lot of work.
The trick here is that React needs to know what things are priority. For example, a user drag-and-drop interaction should be prioritized over rendering a list of items. React can't know what's a priority and what's not, so it needs you to tell it.
You can do this using the useDeferredValue hook. The value you receive from React will be a "deferred value" that React will prioritize less than other work. This is useful for things like rendering a list of items, where the user can still interact with the page even if the list isn't fully rendered yet.
In the Suspense workshop we used this to make a list of items show stale content while we loaded more search results, but it is also used to de-prioritize rendering of less important things.
Here's the example from the React docs:
function App() {
	const [text, setText] = useState('')
	const deferredText = useDeferredValue(text)
	return (
		<>
			<input value={text} onChange={(e) => setText(e.currentTarget.value)} />
			<SlowList text={deferredText} />
		</>
	)
}

const SlowList = memo(function SlowList({ text }) {
	// something really slow happens here...
	return <div>{text}</div>
})
It's important to understand that the initial render of the SlowList will still be slow (there's nothing "old" to show the user while React works in the background), so as with other performance optimizations, it's better to just "make it faster" if you can. However, for if you can't, useDeferredValue can clue React into the fact that re-rendering the App component when the deferredText changes is less important than other work (like keeping the value prop on the input up-to-date).
For some technical background on how useDeferredValue does this, check the documentation.
You must memo-ize the slow component. This is because React needs to be able to rerender the component with the previous value very quickly. So if you don't use memo on the component, React is forced to rerender the entire component with the old value anyway which defeats the purpose of useDeferredValue in this case.