Skip to content

防抖和节流的含义和意义,以及具体实现

🕒 Published at:

防抖(debounce)的含义:限制函数至少间隔多久执行一次

节流(throttle)的含义:限制函数在某段时间内最多执行一次

防抖和节流的意义:避免页面卡顿,掉帧,提升用户体验,常用在onscroll、onresize这类触发非常频繁的事件上

防抖的实现思路:

  • 函数执行过一次后,在n秒内不能再次执行,否则推迟函数执行
  • 下一次函数调用将清除上一次的定时器,并用setTimeout重新计时

具体实现:

js
function debounce(fn, ms) {
    let timer = null;
    return function () {
        if (timer) {
            clearTimeout(timer);
        }
        timer = setTimeout(() => {
            fn.apply(this, arguments);
        }, ms);
    }
}

适用场景:当窗口大小发生变化时计算新的窗口大小、验证用户输入

总结:利用时间间隔推迟函数的执行

节流的实现思路:

  • 函数在n秒内最多执行一次
  • 下一次函数调用将清除上一次的定时器
    • 若函数执行的时间间隔小于等于规定时间间隔则用setTimeout在规定时间后再执行
    • 若函数执行的时间间隔大于规定时间间隔则执行函数,并重新计时

具体实现:

js
function throttle(fn, ms = 300) {
    let timer,
        startTime = new Date();
    return function () {
        if (timer) {
            clearTimeout(timer);
        }
        let currentTime = new Date();
        if (currentTime - startTime <= ms) {
            //小于等于规定时间间隔时,用setTimeout在指定时间后再执行
            timer = setTimeout(() => {
                fn.apply(this, arguments);
            }, ms)
        } else {
            //重新计时并执行函数
            startTime = currentTime;
            fn.apply(this, arguments);
        }
    }
}

适用场景:页面滚动图片懒加载

总结:函数节流可以限制函数的执行频率

函数防抖与函数节流的对比:

首先明确一点:不管是函数节流还是函数防抖,我们减少的是事件处理程序的调用频率,而不是事件的调用频率。每次滚动、每次输入都会触发事件。 函数防抖和函数节流都用了闭包封装

当我们用节流函数或防抖函数封装事件处理程序时,要注意两个问题:

  • 事件对象的传递
  • this的指向