您的位置:

前端防抖——避免不必要的请求

一、什么是前端防抖?

前端防抖指的是在某个时间段内,如果有多个相同事件同时被触发,只会执行最后一次触发事件的函数,并且可以设置等待时间,如果在等待时间内有新的事件触发,就需要重新等待,等待时间结束后才会执行函数。常用于解决重复事件触发导致的浏览器性能问题。

二、前端防抖的应用场景

1、输入框搜索实时联想功能:每当用户输入一个字符就会发起请求,如果页面中有多个输入框,会导致频繁的请求,使用前端防抖可以减少请求次数。

function debounce(func, delay) {
  let timer;
  return function(...args) {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

function search() {
  // 实现搜索功能
}

const inputElement = document.querySelector('input');
inputElement.addEventListener('input', debounce(search, 300));

2、页面滚动懒加载:用户可能不会看到页面所有内容,当页面滚动到某个位置时才会加载一部分内容,如果每滚动一个像素就会发起一次请求,会严重影响页面性能,使用前端防抖可以减少请求次数。

function debounce(func, delay) {
  let timer;
  return function(...args) {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

function loadContent() {
  // 加载内容
}

window.addEventListener('scroll', debounce(loadContent, 300));

三、前端防抖的实现方式

前端防抖有两种实现方式,一种是使用setTimeout函数,一种是使用requestAnimationFrame函数,两种方式都可以有效地避免不必要的请求。

1、使用setTimeout函数实现

function debounce(func, delay) {
  let timer;
  return function(...args) {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
}

上面的代码中,timer表示定时器的编号,当事件触发时,会先判断是否有已经存在的定时器,如果有,则清除已有定时器,然后重新设置一个新的定时器,等待一段时间后执行函数。

2、使用requestAnimationFrame函数实现

requestAnimationFrame函数可以在浏览器绘制下一帧之前执行任务,可以减少不必要的重绘,从而提高性能。

function debounce(func, delay) {
  let timer;
  return function(...args) {
    if (timer) {
      cancelAnimationFrame(timer);
    }
    timer = requestAnimationFrame(() => {
      func.apply(this, args);
    }, delay);
  };
}

与使用setTimeout函数实现的代码类似,只是将setTimeout函数替换成了requestAnimationFrame函数。

四、前端防抖的优化方式

前端防抖虽然可以解决频繁触发事件的问题,但是如果事件触发过于频繁,也会导致大量的请求堆积,影响用户体验。为了避免这种情况,可以对前端防抖进行优化。

1、立即执行一次:如果用户需要立即执行函数,可以在函数执行前加上一个立即执行的代码块。

function debounce(func, delay, immediate) {
  let timer;
  return function(...args) {
    if (timer) {
      clearTimeout(timer);
    }
    if (immediate) {
      immediate = false;
      func.apply(this, args);
    }
    timer = setTimeout(() => {
      if (!immediate) {
        func.apply(this, args);
      }
    }, delay);
  };
}

2、取消防抖:如果用户不需要某个事件的防抖功能,可以取消防抖。

function debounce(func, delay) {
  let timer;
  const debounceFunc = function(...args) {
    if (timer) {
      clearTimeout(timer);
    }
    timer = setTimeout(() => {
      func.apply(this, args);
    }, delay);
  };
  debounceFunc.cancel = function() {
    clearTimeout(timer);
  };
  return debounceFunc;
}

const inputElement = document.querySelector('input');
const debounceSearch = debounce(function() {
  // 实现搜索功能
}, 300);

inputElement.addEventListener('input', debounceSearch);

// 取消防抖
debounceSearch.cancel();

五、总结

前端防抖是一种常用的优化技术,可以避免不必要的请求,提高网页的性能和用户体验。通过本文的介绍,我们了解了前端防抖的实现方式和优化方式,可以更好地应用于实际开发中。