Стабилизация и троттлинг

оптимизация производительности

браузерresize,scroll,keypress,mousemoveКогда событие срабатывает, функция обратного вызова, привязанная к событию, будет постоянно вызываться, что сильно тратит ресурсы и снижает производительность интерфейса. В целях оптимизации опыта необходимо ограничить количество обращений к таким событиям.

Отказаться

Эффект состоит в том, чтобы запускать одну и ту же функцию несколько раз за короткий промежуток времени, только в последний раз или только в начале.

Активируется перетаскиванием пользователем для изменения размера окнаresizeсобытие, например, размер окна менялся во время этого процесса, поэтому, если мы находимся вresizeПривяжите функцию к событию, эта функция будет срабатывать все время, и эта ситуация в большинстве случаев бессмысленна, а также приведет к трате ресурсов.

В настоящее время вы можете использовать функцию защиты от сотрясений для оптимизации связанных операций:

// 普通方案
window.addEventListener('resize', () => {
  console.log('trigger');
})

Оптимизация:

// debounce 函数接受一个函数和延迟执行的时间作为参数
function debounce(fn, delay){
    // 维护一个 timer
    let timer = null;
    
    return function() {
        // 获取函数的作用域和变量
        let context = this;
        let args = arguments;
        
        clearTimeout(timer);
        timer = setTimeout(function(){
            fn.apply(context, args);
        }, delay)
    }
}
function foo() {
  console.log('trigger');
}
// 在 debounce 中包装我们的函数,过 2 秒触发一次
window.addEventListener('resize', debounce(foo, 2000));
  • существуетresizeПривяжите функцию обработчика к событию, затемdebounceФункция вызывается немедленно, когда функция фактически связанаdebounceФункция возвращается внутри функции.
  • Каждое событие запускается, и оно очистит текущийtimerЗатем сбросьте вызов тайм-аута.
  • Только когда событие запускается в последний раз, можетdelayВыполнить по прошествии времени.

мы также можемdebounceПлюс параметр функции, вы можете выбрать, следует ли немедленно выполнять функцию

function debounce(func, delay, immediate){
    var timer = null;
    return function(){
        var context = this;
        var args = arguments;
        if(timer) clearTimeout(timer);
        if(immediate){
            var doNow = !timer;
            timer = setTimeout(function(){
                timer = null;
            },delay);
            if(doNow){
                func.apply(context,args);
            }
        }else{
            timer = setTimeout(function(){
                func.apply(context,args);
            },delay);
        }
    }
}

дроссель

Подобно подавлению дребезга, регулирование позволяет функции выполняться только один раз в течение определенного периода времени.

Сценарии приложений, такие как ассоциация полей ввода, могут ограничить пользователя ответом на ассоциацию только один раз каждые две секунды при вводе.

Этого можно добиться с помощью временных меток и таймеров.

Реализация метки времени:

var throttle = function(func, delay){
    var prev = Date.now();
    return function(){
        var context = this;
        var args = arguments;
        var now = Date.now();
        if(now-prev>=delay){
            func.apply(context,args);
            prev = Date.now();
        }
    }
}

Реализация таймера:

var throttle = function(func, delay){
    var timer = null;
    return function(){
        var context = this;
        var args = arguments;
        if(!timer){
            timer = setTimeout(function(){
                func.apply(context, args);
                timer = null;
            },delay);
        }
    }
}

Отличие состоит в том, что функция регулирования, реализованная с помощью временной метки, будет выполняться сразу же, когда событие инициируется в первый раз, и будет выполняться только через каждые секунды задержки, а последнее событие триггера не будет выполняться; в то время как функция регулирования, реализованная с помощью timer Не будет выполняться при первом срабатывании, но будет выполняться по истечении секунд задержки, и функция будет выполняться снова, когда триггер останавливается в последний раз.

Статьи по Теме

js: антиджиттер и дросселирование

Выравнивание массива, каррирование, защита от сотрясений, дросселирование, копирование объектов