How to debounce in Svelte?
Justin Ahinon
Last updated on
Heads up!
Svelte version: 4.0.5
Here is a scenario (inspired from a real use case I had):
You are trying to build a search interface for Subreddits on Reddit
Every time the user types a character, you want to fetch the list of Subreddits that match the query
And display the results as a list
But here are some problems:
If you send a request to Reddit every time the user types a character, you will quickly hit the API rate limit
Depending on which response you get first, you might end up displaying the results of a query that is not the latest one
How can you solve this problem?
That's the purpose of this article. We will see how to use the debounce technique to solve this problem.
But first, what does "debouncing" mean?
Debouncing is a technique that allows you to delay the execution of a function until a certain amount of time has passed since the last time the function was called.
Think of it this way: you have a button that you can click. Every time you click the button, you want to display a message. But you don't want to display the message every time you click the button. You want to display the message only if you haven't clicked the button for 2 seconds.
Debouncing is a technique that allows you to do that.
Generally, to debounce a function:
You need to keep track of the last time it was invoked
When the function is called, you check how much time has elapsed since the last invocation
If it's been less than the delay you want (e.g. 500ms), you do nothing
If the delay has elapsed, you invoke the function and reset the timer
If you're a video learner, here is a video I refer to every time I need to refresh my memory about debouncing: https://www.youtube.com/watch?v=cjIswDCKgu0.
The benefit is it limits how often the function is actually run. So you can avoid issues like hitting API limits or performing expensive operations too frequently.
Now, let's see how we can apply this technique to our Subreddits search interface.
Naive search interface implementation
Here is how I'd naively and intuitively implement the search interface:
code loading...
I believe the code above is pretty straightforward.
We have a
searchSubreddit
function that is called every time the user types a character on the inputThe function fetches the list of Subreddits that match the query and stores them in the
foundSubreddits
reactive variableThe
foundSubreddits
variable is used to display the list of Subreddits
Here is what it looks like:
You will notice in the screen recording that the list of Subreddits is updated every time I type a character, and the experience is far from ideal. Plus, in that screen recording, I was typing pretty slowly. Imagine if I was typing faster.
Debouncing the search function
Instead of directly calling the searchSubreddit
function every time the user types a character, we will rather call a custom debounce
function that will take the searchSubreddit
function as a callback argument.
Please note that you don't have to implement your own debounce functions all the times (although I strongly advise that in order to have a good understanding of how things work ).
They are libraries out there that you can use. You'll find them with a simple Google search of things like "debounce function JavaScript" or "debounce function TypeScript".
Here is how the debounce
function looks like:
code loading...
Here is what's happening:
We keep track of the
timeout
variableEvery time the function is called, we clear the timeout
We set a new timeout that will call the callback function after the delay we want (300ms by default)
If the function is called again before the delay has elapsed, we clear the timeout and set a new one
Now, not many things change from our previous implementation. We just need to call the debounce
function instead of the searchSubreddit
function:
code loading...
Now, it's not the search function that is called directly. Our debounce function will be called every time the user types a character. And the debounce function will call the search function only if the delay has elapsed.
Here is what it looks like now:
Much better, right? The experience is way smoother. And we can properly control how often the search function is called with the delay we want.
Conclusion
That's it for this article. I hope you enjoyed it and learned something new.
If you have a Svelte or a SvelteKit project, and you need technical help, I offer real-time and asynchronous consulting sessions.
You can learn more and book a session here: https://www.okupter.com/services/svelte-and-svelt ekit-consulting.