更新于 2025-10-03
在前端开发中,防抖(debounce)和限流(throttle)是两个常见的性能优化技巧,主要用于控制高频率事件的触发,比如滚动、输入、窗口缩放等。
下面分别介绍这两个方法,并对它们的区别进行直观讲解。
防抖的作用:
防抖的核心思想是在事件被频繁触发时,只在最后一次触发后过一段时间才执行目标函数。
如果在这段时间内又触发了事件,则重新计时。
这意味着,只会在事件停止触发后,执行最后一次的操作。
实现代码:
function debounceFunction(fn, timeout) {
var timer = 0;
return function() {
if (timer) window.clearTimeout(timer);
var args = arguments, that = this;
timer = window.setTimeout(function() {
fn.apply(that, args);
}, timeout);
};
}
使用示例:
var func = debounceFunction(function(name) {
console.log(name);
}, 500);
func('test1');
func('test2');
func('test3');
func('test4');
// 每调用一次都重置 timer,并设置新的 timeout。
// 在 500ms 内连续多次调用,只会执行最后一次(即 test4)。
直观说明:
比如你将 func
绑定到一个按钮的点击事件上,每次点击都会重新计时。
如果你不断点击,目标函数可能永远不会被执行;只有最后一次点击后等待够了 timeout,才会真正执行。
限流的作用:
限流的核心思想是在高频事件触发时,按照设定的时间间隔(timeout)来执行目标函数。
即使事件被频繁触发,也只会按照固定节奏执行,而不会漏掉首次触发。
实现代码:
function throttleFunction(fn, timeout) {
var last_exec = 0;
return function() {
var now = +new Date();
if (now - last_exec < timeout) return;
last_exec = now;
fn.apply(this, arguments);
};
}
使用示例:
var func = throttleFunction(function(name) {
console.log(name);
}, 500);
func('test1');
func('test2');
setTimeout(function() {
func('test3');
}, 600);
// 这里 func('test2') 不会被执行,因为距离上一次执行未超过 500ms
直观说明:
同样将 func
绑定到按钮点击事件上,无论你多快点击,目标函数第一次一定会执行。
之后每隔 timeout(比如 500ms)才有机会再次执行,期间多次点击只会被忽略。
场景举例:
总结一句话:
防抖关注“最后一次”,限流关注“每隔一段时间”。