前端函数防抖原理与实战实现
在现代 Web 应用中,函数防抖(debounce)是一种常见且高效的性能优化手段。它主要用于限制高频事件触发下的函数调用次数,从而减少不必要的计算、网络请求或 DOM 操作。
为什么使用防抖
函数防抖的核心思想是在连续触发的事件停止后,仅执行最后一次调用。如果不加控制,比如在 input 输入事件或 window.resize 事件中直接处理逻辑,页面很容易因短时间内大量调用而卡顿,甚至引发请求风暴。
通过防抖,我们可以让函数在用户停止输入、滚动或调整窗口大小后的特定延迟内才执行。这不仅提高了资源利用效率,也能显著提升用户体验。
函数防抖的应用场景
-
输入框实时搜索建议 用户输入关键词时若每次
keyup都发请求,接口压力会很大。加上防抖后,只在用户停止输入(比如 300ms)后才发送请求,能有效降低调用频率。 -
按钮防连点 对于提交表单或支付按钮,连续点击可能导致多次提交。绑定防抖函数后,短时间内多次点击只会执行一次操作。
-
窗口大小调整(resize) 当布局需根据窗口大小实时重绘时,
resize事件触发非常频繁。添加防抖能减少重绘次数,避免性能抖动。 -
滚动监听 结合无限滚动或懒加载时,控制数据加载频率至关重要,防止重复请求或过度渲染。
函数防抖原理与手写实现
原理
防抖函数内部维护一个定时器 ID。每次调用时先清除之前的定时器,再启动一个新的延迟执行定时器;只有在最后一次调用后的延迟时间到达后,才真正执行目标函数。
手写实现
这里提供一个基础版本,利用闭包来维护独立的 timeoutId:
/**
* 简易版防抖函数
* @param {Function} func - 需要防抖的函数
* @param {number} wait - 延迟时间(毫秒)
* @returns {Function} - 防抖后返回的新函数
*/
function debounce(func, wait) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
func.apply(this, args);
}, wait);
};
}
这段代码的关键在于 clearTimeout 和 setTimeout 的配合。每次调用都会重置计时器,确保只有最后一次调用会在等待结束后触发回调。


