What is debouncing and throttling?
Debouncing and throttling are too common techniques for dealing with things that happen "too often". Imagine you're meeting a friend, and they are telling you a story, but they struggle to pause when talking. Let's say you want to accommodate them while also responding to what they have to say, when possible. (I know this might be a bit contrived, but bear with me!)
Let's say you can never speak at the same time. You have a few strategies:
Synchronous
You could respond to each sentence the moment they finish it:
This might work okay if your responses are short. But if your responses are longer, this could make it very hard for them to finish the story. So this strategy isn't great.
Debounced
You could wait for them to stop talking. For example, if they pause for long enough, you could start responding:
This strategy works well if your friend is occasionally making pauses. However, if they're talking for a few minutes without a pause, this doesn't let you respond at all:
Throttled
You could decide to respond at most once a minute. Here, you keep count of how long you haven't spoken for. Once you haven't spoken for a minute, you insert your response right after the friend's next sentence:
This strategy is helpful if your friend wants you to respond as they go, but they don't ever create pauses for you to do it. But it's not great if they're creating pauses but you're still waiting out for no reason:
How does this relate to React?
Friend's "sentences" are events like button clicks or keyboard typing. Your "responses" are updating the screen.
You use debouncing or throttling when the user is doing something too fast (e.g. typing), and updating the screen in response to each individual event is just too slow. So you either wait for the user to stop typing (debouncing) or you update the screen once in a while, like once a second (throttling).
What about React 18?
The interesting thing is that startTransition makes both strategies unnecessary for many cases. Let's add one more strategy that you didn't have before React 18:
Cooperative
You start responding immediately the moment your friend finishes a sentence, without waiting. But you've agreed with your friend that they may interrupt you if they want to keep going. So in that case you'll abandon your attempt to respond. Right after the next sentence, you'll try again. And so on:
(You also agree that you will interrupt them if enough time has passed and you still haven't managed to respond. This prevents the case where you don't get to speak for too long.)
Note how in this strategy you're not wasting any time and also don't prevent your friend from continuing.
This gives you the best of all three previous approaches. (Who would have thought that being cooperative helps!)
In the coding example, this means that React starts rendering immediately after the user types. There's no need to delay doing it (like debouncing does). If the user types again, React will just abandon that work and start again. If rendering was fast enough to fit in the pause between events, then you haven’t wasted any time (by waiting unnecessarily). You’re also not wasting time on finishing a render that's no longer needed.
You can see a demo of the difference here. Try typing into the input. The more you type, the more complex graph we draw (artificially slowed down to show the point). See the different behavior between the three strategies. How do they behave when as you keep typing longer text into the input?
Which one feels smoother?





