节流(Throttle)和防抖(Debounce)是两个在前端开发中常用的技术,它们用于控制某些函数的执行频率,以提升性能和用户体验。虽然两者的目标相似,但实现方式和适用场景有所不同。
一、节流(Throttle)
-
定义
节流是一种在一定时间间隔内只允许某个函数执行一次的方法。如果在这个时间间隔内多次调用函数,只有一次会生效,其余的调用会被忽略。 -
适用场景
节流适用于那些在一段时间内会频繁触发的事件,但又不需要每次都响应的场景。例如:
滚动事件(scroll)
窗口调整大小事件(resize)
鼠标移动事件(mousemove)
3. 实现原理
节流的实现通常有两种方式:时间戳方式和定时器方式。
时间戳方式:
function throttle(func, wait) {//参数为要执行函数和间隔时间let previous = 0;//用于记录上次执行时间return function(...args) {//匿名函数,rest参数用法,arg数组存储了throttle参数,用于下次调用const now = Date.now();//本次调用时间戳if (now - previous > wait) {//判断两次调用时间间隔是否过短previous = now;//更新时间戳func.apply(this, args);//}};
}
时间戳是一个表示某个时刻的数字,通常是从1970年1月1日00:00:00 UTC到当前时刻的毫秒数。Date.now()方法返回当前的时间戳。
apply 是 JavaScript 中的一个函数方法,用于调用一个函数,并且可以指定函数的执行上下文 (this 值) 以及参数数组。它是 Function 对象的一个方法,与 call 方法类似,但它接受参数数组而不是单个参数。
func.apply(thisArg, [argsArray])
定时器方式:
function throttle(func, wait) {let timeout = null;return function(...args) {if (!timeout) {timeout = setTimeout(() => {timeout = null;func.apply(this, args);}, wait);}};
}
二、防抖(Debounce)
-
定义
防抖是一种在函数调用后一定时间内不再调用该函数的方法。也就是说,如果在这段时间内再次调用该函数,则重新计时,只有在这段时间结束后,函数才会被执行。 -
适用场景
防抖适用于那些在一段时间内会频繁触发的事件,但又希望最终只执行一次的场景。例如:
搜索框输入(input)联想
表单验证
浏览器窗口大小调整(resize)
3. 实现原理
防抖的实现通常使用定时器。
基本实现:
function debounce(func, wait) {let timeout;return function(...args) {clearTimeout(timeout);timeout = setTimeout(() => {func.apply(this, args);}, wait);};
}
三、对比与总结
控制频率方式不同:
节流:保证在一定时间内执行一次,无论触发频率多高。
防抖:在一定时间内不再触发,若在这段时间内再次触发,则重新计时。
适用场景不同:
节流适用于频繁触发但需要定期执行的场景。
防抖适用于频繁触发但只需执行一次的场景。
实现方式不同:
节流可以通过时间戳或定时器实现。
防抖通常通过定时器实现。
四、例子
节流示例
应用于页面滚动事件:
window.addEventListener('scroll', throttle(() => {console.log('Scroll event handler called');
}, 100));
防抖示例
应用于输入框搜索建议:
const searchInput = document.getElementById('search');
searchInput.addEventListener('input', debounce(() => {console.log('Input event handler called');
}, 300));
通过合理使用节流和防抖技术,可以有效提升前端应用的性能和用户体验,避免不必要的资源浪费和重复执行。