Tutorial

Throttling and Debouncing Events with Vue.js and lodash

Updated on February 20, 2021
author

Joshua Bemenderfer

Throttling and Debouncing Events with Vue.js and lodash

Introduction

Event throttling and debouncing refer to two approaches to improve performance and potentially lower network overhead.

While Vue.js 1 used to have native support for debouncing events, it was removed in Vue.js 2.

As a result, a common approach to throttling and debouncing events in Vue.js 2 is through third-party libraries, like lodash.

In this tutorial, you will apply lodash.throttle and lodash.debounce to a Vue.js 2 application.

Prerequisites

If you would like to follow along with this article, you will need:

This tutorial was verified with Node v15.8.0, npm v7.5.4, vue v2.6.11, and lodash v4.17.20.

Setting Up the Project

To quickly set up the project, this article will recommend using @vue/cli.

Note: This article will take the approach of using npx to avoid a global installation of @vue/cli;

  1. npx @vue/cli create vue-lodash-example

After selecting a preset (Default ([Vue 2] babel, eslint)) and package manager (npm), navigate to the newly created project directory;

  1. cd vue-lodash-example

Now, you will want to add lodash to the project with the following command:

npm install lodash

Note: If you do not need to import all of lodash, customizing webpack can reduce the size of the library to the functions that are utilized. It is also possible to import parts of lodash separately, in packages like lodash.throttle and lodash.debounce.

Next, use your code editor to create a new UnmodifiedComponent.vue file in the components directory:

src/components/UnmodifiedComponent.vue
<template>
  <div>
    <h1>Unmodified Events</h1>
    <button @click="unmodifiedMethod()">Click this button as fast as you can!</button>
  </div>
</template>

<script>
export default {
  methods: {
    unmodifiedMethod: () => {
      console.log('Button clicked!')
    }
  }
}
</script>

Next, modify App.vue to use the new UnmodifiedComponent:

src/App.vue
<template>
  <div id="app">
    <UnmodifiedComponent/>
  </div>
</template>

<script>
import UnmodifiedComponent from './components/UnmodifiedComponent.vue'

export default {
  name: 'App',
  components: {
    UnmodifiedComponent
  }
}
</script>

Now you can run the Vue.js application:

  1. npm run serve

Navigate to localhost:8080 in your web browser and interact with the button in your web browser. The console will log all of your interactions. These events will fire immediately with every click. You will be modifying this method to use throttle and debounce.

Throttling Methods

Next, you will apply throttle to your Vue application. Throttling can be used to ensure your events are preserved but separated over time.

Use your code editor to copy your UnmodifiedComponent and create a new ThrottleComponent:

ThrottleComponent.vue
<template>
  <div>
    <h1>Throttled Events</h1>
    <button @click="throttleMethod()">Click this button as fast as you can!</button>
  </div>
</template>

<script>
import _ from 'lodash'

export default {
  methods: {
    throttleMethod: _.throttle(() => {
      console.log('Throttle button clicked!')
    }, 2000)
  }
}
</script>

Next, modify App.vue to use the new ThrottleComponent:

src/App.vue
<template>
  <div id="app">
    <UnmodifiedComponent/>
    <ThrottleComponent/>
  </div>
</template>

<script>
import UnmodifiedComponent from './components/UnmodifiedComponent.vue'
import ThrottleComponent from './components/ThrottleComponent.vue'

export default {
  name: 'App',
  components: {
    UnmodifiedComponent,
    ThrottleComponent
  }
}
</script>

Now you can run the Vue.js application:

  1. npm run serve

Navigate to localhost:8080 in your web browser and interact with the button in your web browser. The console will log all of your interactions. Multiple sequential events will fire consistently with a delay of 2000 milliseconds (2 seconds).

Debouncing Methods

Next, you will apply debounce to your Vue application. Debouncing essentially groups your events together and keeps them from being fired too often.

Use your code editor to copy your UnmodifiedComponent and create a new DebounceComponent:

DebounceComponent.vue
<template>
  <div>
    <h1>Debounced Events</h1>
    <button @click="debounceMethod()">Click this button as fast as you can!</button>
  </div>
</template>

<script>
import _ from 'lodash'

export default {
  methods: {
    debounceMethod: _.debounce(() => {
      console.log('Debounce button clicked!')
    }, 2000)
  }
}
</script>

Next, modify App.vue to use the new DebounceComponent:

src/App.vue
<template>
  <div id="app">
    <UnmodifiedComponent/>
    <ThrottleComponent/>
    <DebounceComponent/>
  </div>
</template>

<script>
import UnmodifiedComponent from './components/UnmodifiedComponent.vue'
import ThrottleComponent from './components/ThrottleComponent.vue'
import DebounceComponent from './components/DebounceComponent.vue'

export default {
  name: 'App',
  components: {
    UnmodifiedComponent,
    ThrottleComponent,
    DebounceComponent
  }
}
</script>

Now you can run the Vue.js application:

  1. npm run serve

Navigate to localhost:8080 in your web browser and interact with the button in your web browser. The console will log all of your interactions. Multiple sequential events will only fire after the last click once every 2000 milliseconds (2 seconds).

Conclusion

In this tutorial, you applied lodash.throttle and lodash.debounce to a Vue.js 2 application.

If you’d like to learn more about lodash, read the the official documentation.

If you’d like to learn more about Vue.js, check out our Vue.js topic page for exercises and programming projects.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors
Default avatar
Joshua Bemenderfer

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
3 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

And if you need to access the component instance inside the throttled function, then simply dont use an arrow function:

data: () => ({ stuff }),
methods: {
    throttledMethod: _.throttle(function() {
      console.log(`I get fired every two seconds! and have access to this.stuff !`)
    }, 2000)
  }

Linus Borg, a core member of the Vuejs team, recommends creating debounced methods in created() [1], to avoid wonky behavior across instances.

In this case, it would look like so:

import _ from 'lodash'

export default {
  created() {
    this.logMessage = _.debounce(this.logMessage, 2000)
  },
  methods: {
    logMessage() {
      console.log('I only get fired once every two seconds, max!')
    }
  }
}

1: https://forum.vuejs.org/t/lodash-debounce-not-working-when-placed-inside-a-method/86334/5

If you only need the debounce function, you can import it by itself:

import { debounce } from 'lodash'

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Become a contributor for community

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

DigitalOcean Documentation

Full documentation for every DigitalOcean product.

Resources for startups and SMBs

The Wave has everything you need to know about building a business, from raising funding to marketing your product.

Get our newsletter

Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

New accounts only. By submitting your email you agree to our Privacy Policy

The developer cloud

Scale up as you grow — whether you're running one virtual machine or ten thousand.

Get started for free

Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

*This promotional offer applies to new accounts only.