您的位置:

节流防抖详解及代码示例

一、什么是节流和防抖?

在前端开发中,由于用户的交互行为导致的频繁触发事件会导致浏览器的性能问题。我们可以通过使用节流和防抖来限制这种触发,以提高浏览器的性能。

1. 节流

所谓节流,就是对一段时间内连续的事件进行忽略,只对首次或最后一次事件进行处理。


function throttle(fn, delay) {
  let lastTime = 0;
  return function() {
    const nowTime = new Date().getTime();
    if (nowTime - lastTime > delay) {
      fn();
      lastTime = nowTime;
    }
  }
}

const fn1 = () => console.log('Throttle');
window.addEventListener('scroll', throttle(fn1, 1000));

上述代码中,我们定义了一个节流函数throttle,它接受两个参数:要执行的函数fn和时间间隔delay,返回一个新函数。在新函数的内部,我们定义了lastTime变量,用来记录上一次执行fn的时间,然后在每次执行时,判断当前时间和上一次执行的时间差是否大于delay,如果是,则执行fn,并更新lastTime为当前时间。

2. 防抖

防抖是对连续的事件进行忽略,只对最后一次事件进行处理。


function debounce(fn, delay) {
  let timer = null;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  }
}

const fn2 = () => console.log('Debounce');
window.addEventListener('scroll', debounce(fn2, 1000));

防抖函数debounce也接受两个参数:要执行的函数fn和时间间隔delay,返回一个新函数。在新函数的内部,我们定义了timer变量,用来记录定时器的ID,然后在每次执行时,清除掉之前的定时器,并重新设置一个新的定时器。如果在delay的时间内,定时器的回调函数没有被执行,那么就说明已经过了delay时间,这时候我们就可以执行fn。

二、节流和防抖的使用场景

1. 节流

节流适用于需要高频率触发的事件,比如鼠标移动事件、窗口大小改变事件等。


function throttle(fn, delay) {
  let lastTime = 0;
  return function() {
    const nowTime = new Date().getTime();
    if (nowTime - lastTime > delay) {
      fn();
      lastTime = nowTime;
    }
  }
}

const fn1 = () => console.log('Throttle');
window.addEventListener('mousemove', throttle(fn1, 100));

在上述代码中,我们可以看到,节流函数被用于监听鼠标移动事件。假设我们没有使用节流,那么每次鼠标移动都会触发事件,这样会极大地影响浏览器的性能,使用节流后,鼠标移动事件在100毫秒内只会触发一次,这样就避免了频繁触发事件导致的性能问题。

2. 防抖

防抖适用于需要延迟处理的事件,比如搜索框输入事件,我们希望用户输入后在一定时间内没有进行下一次输入操作,则开始发起搜索请求。


function debounce(fn, delay) {
  let timer = null;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timer);
    timer = setTimeout(function() {
      fn.apply(context, args);
    }, delay);
  }
}

const fn3 = (value) => console.log(`Search: ${value}`);
const input = document.querySelector('input');
input.addEventListener('input', debounce(() => fn3(input.value), 500));

上述代码中,我们监听了input的输入事件,并且使用了防抖函数。假设用户在500毫秒内一直在输入,那么防抖函数的定时器会一直被重置,直到用户在500毫秒内没有进行输入操作,定时器的回调函数才会被执行,从而发起搜索请求。

三、节流和防抖的优缺点

1. 节流

节流的优点在于可以控制在一定时间内只触发一次事件,避免频繁触发事件导致的性能问题。同时,节流函数也比较简单,容易理解和使用。

缺点在于,由于在一定时间内只触发一次事件,所以在该时间内累计的事件会被忽略,可能会导致用户操作的不连贯性。

2. 防抖

防抖的优点在于可以延迟处理事件,避免在用户频繁操作时频繁触发事件导致的性能问题。同时,防抖函数也可以控制输入框等需要延迟处理的组件的行为,提升用户体验。

缺点在于,防抖函数在一段时间内只执行最后一次事件,而前面的事件都会被忽略,可能导致用户操作的不连贯性。

四、小结

综上所述,节流和防抖是前端开发中非常实用的工具,可以控制事件被触发的频率,从而避免浏览器的性能问题。节流适用于高频率触发的事件,而防抖适用于需要延迟处理的事件。使用节流和防抖可以提升用户体验,并且提高应用程序的响应速度。