Implementing Debouncing in Vue
Tags: vue, nuxt, typescript, javascript
Published: 2024-02-26 10:31:55

When I first learned about the concept of debouncing I instantly liked it and started implementing it whenever I had opportunity to do so. In one of my previous projects we had a search bar that was basically fetching search results after each key press. 

This resulted in bad User Experience and huge amount of requests sent to our search service (which was a third party application where each request matters and can be expensive). I had a talk about implementing this debouncing with my friend about User Experience of such solution. 

In general, implementation of debouncing does not change functionality of your application that much, however, depending on the users that might be using your system, you may need to discuss what should be the appropriate debouncing time (so called timeout).

## 🤔 What is Debouncing?

Debouncing is removing unwanted input noise from buttons, switches or other user input. Debouncing prevents extra activations or slow functions from triggering too often.

Take a look at the visual representation below to understand better how does the debouncing work in input elements (the most common use case):

<img width="100%" style="width:100%" src="https://miro.medium.com/v2/resize:fit:1400/1*-r8hP_iDBPrj-odjIZajzw.gif">

So in general, the concept is relatively simple. Let's take a look at the implementation examples.

## 🟢 Debouncing in Vue

There are multiple ways how you can implement debouncing in Vue so let's start from the easiest one - pure JavaScript. There is a built in method in JS called `setTimeout` that allows you to trigger some functionality after certain period of time. We can use it in our `debounce` method like following:

```ts
export function debounce(fn, wait){
    let timer;
   return function(...args){
     if(timer) {
        clearTimeout(timer); // clear any pre-existing timer
     }
     const context = this; // get the current context
     timer = setTimeout(()=>{
        fn.apply(context, args); // call the function if time expires
     }, wait);
   }
}
```

As mentioned, this is a pure JS solution that will work nicely. But there might be some cases where you may want to have someting more Vue specific like having access to reactive properties that will be updated automatically like `ref` or `computed`. For that, you may want to try out VueUse and more specifically the `useDebounceFn` composable:

```ts
import { useDebounceFn } from '@vueuse/core'

const debouncedFn = useDebounceFn(() => {
  // do something
}, 1000)

window.addEventListener('resize', debouncedFn)
```

You can read more about this composable [here](https://vueuse.org/shared/useDebounceFn/).

## 📖 Learn more 

There is a great course about VueUse from Vue School that you can check out with this [link](https://vueschool.io/lessons/debounce-the-search-input?friend=baroshem) or by clicking the image below:

[![Vue School Link](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/i662jpyni4zs2dlaeud1.png)](https://vueschool.io/lessons/debounce-the-search-input?friend=baroshem)

It covers most important composables to help you handle browser, sensors, animation and other useful utilities in an easy and Vue-like way 😉

## ✅ Summary

Well done! You have just learned about the concept of debouncing and how you can utilize it in Vue to trigger some functionality after certain amount of time. 

Take care and see you next time!

And happy coding as always 🖥️