前端性能优化之 防抖和节流

149 阅读2分钟

防抖与节流:优化事件处理的性能

在开发过程中,我们经常会遇到需要优化事件处理性能的场景。本文将介绍两种常用的技术:防抖(debounce)和节流(throttle),并提供实现思路和代码示例。

防抖(Debounce)

概念

事件连续触发,防抖函数在设定时间内没有被触发过才会执行事件函数,在设定时间内如果被触发过,就会重新计时,从而防止事件被频繁触发;

应用场景

  • 搜索框输入:在用户完成输入后,才发送搜索请求。
  • 窗口调整:在用户停止调整窗口大小时,再计算布局。
  • 点击按钮:当用户点击某些按钮时,会调用接口,防止用户连续点击后多次发送请求。

实现思路

  1. 定义一个防抖函数,接收事件函数和等待时间作为参数。
  2. 使用一个变量来存储定时器,用来控制事件函数是否执行。
  3. 返回一个回调函数,在事件触发时调用,清除旧的定时器并返回一个新的定时器,在定时器内使用 apply 方法调用事件函数,并保存this指向。
js
// 防抖函数实现
function debounce(func, wait) {
    let timeout = null;
    return function(...args) {
        const context = this;
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            func.apply(context, args);
        }, wait);
    };
}

// 使用示例
const inputDom = document.getElementById('debounceInput');
inputDom.oninput = debounce((e) => {
    console.log('查询参数', e.target.value);
}, 500);

节流(Throttle)

概念

事件连续触发,节流技术控制事件函数,在设定的时间内只执行一次,降低事件触发的频次;

应用场景

  • 滚动加载:在用户滚动页面时,控制加载更多内容的频率。
  • 鼠标跟踪:跟踪鼠标移动的位置,但限制事件触发的频率。

实现思路

  1. 使用一个变量来存储定时器,控制事件函数是否可以执行的标识。
  2. 返回一个回调函数,在事件触发时调用,判断变量是否是“忙碌”状态。
  3. 如果状态为“不忙碌”,执行事件函数并设置定时器。
  4. 如果状态为“忙碌”,就不执行事件函数,等待定时器重置变量。
js
// 节流函数实现
function throttle(func, wait) {
    let timer = null;
    return function(...args) {
        if (!timer) {
            func.apply(this, args);
            timer = setTimeout(() => {
                timer = null;
            }, wait);
        }
    };
}

// 使用示例
window.addEventListener('scroll', throttle((e) => {
    console.log('节流参数', window.scrollY);
}, 500));

结论

通过使用防抖和节流技术,我们可以有效地控制事件处理的频率,从而提高应用的性能和用户体验。这两种技术各有适用场景,选择合适的技术可以解决特定的性能问题。