preface

When events such as resize, Scroll, Keypress, and Mousemove of the browser are triggered, the callback functions bound to the events are constantly invoked, which greatly wastes resources and reduces front-end performance. To optimize the experience, you need to limit the number of calls to these events.

Image stabilization

Take the user dragging and dropping to change the size of the window, triggering the REsize event. During this process, the size of the window changes all the time. Therefore, if we bind the function in the resize event, the function will be triggered all the time, which in most cases is meaningless and will cause a large waste of resources.

In this case, you can optimize the operation by using function anti-shake:

function debounce(fn, delay = 1000) {
    let timer;
    return function () {
        window.clearTimeout(timer);
        timer = setTimeout(() = > {
            fn.apply(this.arguments);
            window.clearTimeout(timer); }, delay); }}// Perform function buffeting
let debounced = debounce(function () {
    console.log('debounce');
});

// Listen for resize events
window.addEventListener('resize', debounced);
Copy the code

The debounce function is executed first, returning the internal function (the function that was actually called). Each time the resize event is fired, the returned internal function is fired and the current timer is cleared and the timer is reset. The internal timer function fn can only be invoked after the delay time if the resize event is terminated.

Schematic diagram:



Note: Execute only once during event firing.

The throttle

Do not execute the events that are expected to be executed consecutively when triggered. This will cause a waste of resources. It should be executed at the same interval, not consecutively. For example, lazy image loading based on scroll event.

Function throttling can be used to optimize operations:

function throttle(fn, delay = 1000) {
    // Throttle switch
    let run = true;
    // return the function
    return function () {
        if(! run) {return;
        }
        let timer = setTimeout(() = > {
            fn.apply(this.arguments);
            window.clearTimeout(timer);
            run = true;
        }, delay);

        run = false; }}// perform function throttling
let throttled = throttle(function () {
    console.log('throttle');
});

// Listen for scroll events
window.addEventListener('scroll', throttled);
Copy the code

Execute throttle first and return the internal function (the function actually called). As the window scrolls, the Scroll event will continue to fire and the internal function will execute FN in unit time interval according to the throttle switch.

Schematic diagram:



Note: Only execute multiple times in the same time interval during event firing.