Analysis of examples of using anti-shake and throttling in Vue components

Analysis of examples of using anti-shake and throttling in Vue components

Be careful when listening for events that are triggered frequently, such as user typing in an input box, window resizing, scrolling, and Intersection Observer events.

These events are always triggered frequently, perhaps once every few seconds. It would be unwise to initiate a fetch request (or something similar) for every event.

All we need to do is slow down the execution of our event handlers. This buffering technology is debounce and throttle.

1. Observer Stabilization

Let's start with a simple component. Our task is to output the text entered by the user into the text box to the console:

<template>
  <input v-model="value" type="text" />
  <p>{{ value }}</p>
</template>
<script>
export default {
  data() {
    return {
      value: "",
    };
  },
  watch:
    value(newValue, oldValue) {
      console.log("Value changed: ", newValue);
    }
  }
};
</script>

Open the demo:

https://codesandbox.io/s/vue-input-szgn1?file=/src/App.vue

Open the demo and type a few characters in the input box. Each time an entry is made, the value is logged to the console.

We implement logging by using a watcher to monitor the value data property. But if you want to add a GET request with value as parameter in the observer callback, you probably don't expect to make the request too often.

Let's debounce the behavior of printing console logs. The core idea is to create a debounce function and then call that function inside the observer.

I have chosen the 'lodash.debounce' debounce implementation here, but you are free to choose your preferred implementation.

Let's apply the anti-shake logic to the component:

<template>
  <input v-model="value" type="text" />
  <p>{{ value }}</p>
</template>
<script>
import debounce from "lodash.debounce";
export default {
  data() {
    return {
      value: "",
    };
  },
  watch:
    value(...args) {
      this.debouncedWatch(...args);
    },
  },
  created() {
    this.debouncedWatch = debounce((newValue, oldValue) => {
      console.log('New value:', newValue);
    }, 500);
  },
  beforeUnmount() {
    this.debouncedWatch.cancel();
  },
};
</script>

Try the demo

https://codesandbox.io/s/vue-input-debounced-4vwex?file=/src/App.vue

If you open this demo, you will find that from the user's perspective, not much has changed: you can still enter characters freely as in the previous demo.

But there is one difference: new input values ​​are logged to the console only after 500ms of the last input. This shows that the anti-shake function is working.

Observer anti-shake implementation only requires 3 simple steps:

In the create() hook, create the debounce callback and assign it to the instance: this.debouncedWatch = debounce(..., 500).

Call this.debouncedWatch() with the correct arguments in the observer callback watch.value() { ... }.

Finally, this.debouncedWatch.cancel() is called in the beforeUnmount() hook to cancel all pending debounce function executions before uninstalling the component.

In the same way, you can apply debouncing to observers of any data property. Then you can safely perform some heavier operations inside the anti-shake callback, such as network requests, heavy DOM operations, and so on.

2. Event Processor Anti-shake

In the previous section, I showed how to use anti-shake for observers, but what about regular event handlers?

We'll reuse the previous example where the user enters data into an input box, but this time we'll add an event handler to the input box.

As usual, if you don't take any buffering measures, every time the value is modified it will be printed to the console:

<template>
  <input v-on:input="handler" type="text" />
</template>
<script>
export default {
  methods: {
    handler(event) {
      console.log('New value:', event.target.value);
    }
  }
};
</script>

Try the demo:

https://codesandbox.io/s/vue-event-handler-plls4?file=/src/App.vue

Open this demo and type a few characters in the input box. Take a look at the console: you will see that every time you type something is printed out.

Likewise, if you are performing some heavy operations (such as network requests), this may not be suitable.

To use anti-shake for event handlers, you can refer to the following:

<template>
  <input v-on:input="debouncedHandler" type="text" />
</template>
<script>
import debounce from "lodash.debounce";
export default {
  created() {
    this.debouncedHandler = debounce(event => {
      console.log('New value:', event.target.value);
    }, 500);
  },
  beforeUnmount() {
    this.debouncedHandler.cancel();
  }
};
</script>

Try the demo:

https://codesandbox.io/s/vue-event-handler-debounced-973vn?file=/src/App.vue

Open the demo and enter some characters. The component will log new input values ​​to the console only after 500ms of the last input. Anti-shake works again!

The implementation of event handler de-shaking only requires 3 steps:

.In the create() hook, after creating the instance, immediately assign the debounce callback debounce(event => {...}, 500) to this.debouncedHandler .

In the input box's template, assign a debouncedHandler to v-on:input:

Finally, before unmounting the component, call this.debouncedHandler.cancel() in the beforeUnmount() hook to cancel all pending function calls.

On the other hand, these examples use anti-shake technology. However, the same approach can be used to create throttling functions.

3. Note

You may not understand: why not just create the anti-shake function in the component's method option, and then call these methods as event handlers in the template?

// ...
  methods: {
    // Why not?
    debouncedHandler: debounce(function () { ... }}, 500)
  }
// ...

This is much simpler than creating a debounce function on the instance object.

For example:

<template>
  <input v-on:input="debouncedHandler" type="text" />
</template>
<script>
import debounce from "lodash.debounce";
export default {
  methods: {
    // Don't do this!
    debouncedHandler: debounce(function(event) {
      console.log('New value:', event.target.value);
    }, 500)
  }
};
</script>

Try the demo

https://codesandbox.io/s/vue-event-handler-debounced-incorrectly-320ci?file=/src/App.vue

This time, instead of creating the debounce callback in the created() hook, the debounce callback is assigned to methods.debouncedHandler.

If you try the demo, you will find that it works!

The problem is that the options object exported by a component using export default { ... }, including methods, will be reused by component instances.

If there are more than 2 instances of the component on the page, all components will have the same debounce function methods.debouncedHandler applied - this can cause debounce to malfunction.

4. Conclusion

In Vue, it is easy to apply debouncing and throttling to watchers and event handlers.

The core logic is to create an anti-shake or throttling callback in the created() hook and assign it to the instance.

// ...
  created() {
    this.debouncedCallback = debounce((...args) => {
      // The debounced callback
    }, 500);
  },
// ...

A) Then inside the observer call the debounce function on the instance:

// ...
  watch:
    value(...args) {
      this.debouncedCallback(...args);
    },
  },
// ...

B) Or set an event handler in the template:

<template>
  <input v-on:input="debouncedHandler" type="text" />
</template>

After this, each time this.debouncedCallback(...args) is called, the internal callback can be buffered even if the execution frequency is very high.

This concludes this article on the analysis of anti-shake and throttling examples in Vue components. For more information on the use of Vue components, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • How to use anti-shake and throttling in Vue
  • Correct use of Vue function anti-shake and throttling
  • Vue2.x - Example of using anti-shake and throttling
  • A brief analysis of VUE anti-shake and throttling
  • Using lodash in Vue to de-shake and throttle events
  • How to use anti-shake and throttling in Vue

<<:  VMware, nmap, burpsuite installation tutorial

>>:  How to implement blank space in Taobao with CSS3

Recommend

How to modify create-react-app's configuration without using eject

1. Why is eject not recommended? 1. What changes ...

About VUE's compilation scope and slot scope slot issues

What are slots? The slot directive is v-slot, whi...

Detailed explanation of CSS elastic box flex-grow, flex-shrink, flex-basis

The functions of the three attributes flex-grow, ...

Apache Bench stress testing tool implementation principle and usage analysis

1: Throughput (Requests per second) A quantitativ...

Detailed tutorial on using Docker to build Gitlab based on CentOS8 system

Table of contents 1. Install Docker 2. Install Gi...

CocosCreator Skeleton Animation Dragon Bones

CocosCreator version 2.3.4 Dragon bone animation ...

jQuery implements the function of adding and deleting employee information

This article shares the specific code of jQuery t...

Steps to restore code from a Docker container image

Sometimes the code is lost and you need to recove...

Write a mysql data backup script using shell

Ideas It's actually very simple Write a shell...

How MLSQL Stack makes stream debugging easier

Preface A classmate is investigating MLSQL Stack&...

FlashFXP ftp client software registration cracking method

The download address of FlashFXP is: https://www....

Use Xshell to connect to the Linux virtual machine on VMware (graphic steps)

Preface: I recently started to study the construc...