返回

高频事件处理的两种妙招:函数防抖和节流

前端

在前端开发中,我们常常会遇到需要处理高频事件的场景,例如浏览器的 resizescrollkeypressmousemove 等事件。这些事件在触发时,会不断地调用绑定在事件上的回调函数,极大地浪费资源,降低前端性能。为了优化体验,需要对这类事件进行调用次数的限制。

函数防抖和函数节流是两种常用的高频事件处理技术。它们都能有效地减少函数的调用次数,从而优化前端性能。

函数防抖

函数防抖的原理是,在事件被触发后,创建一个延迟器,并在延迟器到期之前,忽略所有后续的事件触发。当延迟器到期后,执行函数。

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

函数防抖的典型应用场景是搜索框的自动完成功能。当用户在搜索框中输入字符时,会触发 input 事件。如果不对 input 事件进行处理,那么当用户快速输入时,会频繁地触发 input 事件,导致自动完成功能不断地显示和隐藏,影响用户体验。

使用函数防抖后,当用户快速输入时,自动完成功能不会频繁地显示和隐藏。这是因为函数防抖会创建一个延迟器,并在延迟器到期之前,忽略所有后续的 input 事件触发。当延迟器到期后,执行自动完成功能。

函数节流

函数节流的原理是,在事件被触发后,只执行一次函数。如果在函数执行期间,事件又被触发,则忽略后续的事件触发。

function throttle(fn, delay) {
  let lastTime = 0;
  return function () {
    const context = this;
    const args = arguments;
    const now = new Date().getTime();
    if (now - lastTime >= delay) {
      fn.apply(context, args);
      lastTime = now;
    }
  };
}

函数节流的典型应用场景是窗口的滚动事件。当用户滚动窗口时,会触发 scroll 事件。如果不对 scroll 事件进行处理,那么当用户快速滚动窗口时,会频繁地触发 scroll 事件,导致页面不断地重新渲染,影响用户体验。

使用函数节流后,当用户快速滚动窗口时,页面不会频繁地重新渲染。这是因为函数节流会只执行一次 scroll 事件。如果在 scroll 事件执行期间,窗口又被滚动,则忽略后续的 scroll 事件触发。

总结

函数防抖和函数节流都是处理高频事件的有效技术。它们都能有效地减少函数的调用次数,从而优化前端性能。

函数防抖适用于需要在事件触发后,延迟一段时间再执行函数的场景。例如,搜索框的自动完成功能。

函数节流适用于需要在事件触发后,只执行一次函数的场景。例如,窗口的滚动事件。

在实际开发中,我们可以根据不同的场景选择合适的函数处理技术,以优化前端性能,提升用户体验。