防抖(Debouncing)是一种前端开发中常用的技术,用于限制函数的执行频率。在防抖的机制下,一个函数在一定时间内只会执行一次,即使它被频繁地调用。
具体来说,防抖的实现方式是设置一个定时器,在每次函数被调用时,先清除之前的定时器,然后重新设置一个新的定时器。如果在设定的时间间隔内没有再次调用该函数,定时器触发,函数才会被执行。这样可以确保函数不会在短时间内被频繁执行,从而减轻性能压力和提高用户体验。
防抖的应用场景包括输入框输入、滚动事件、窗口大小改变等需要控制执行频率的操作。在这些场景下,防抖可以避免不必要的函数执行,节省资源和提高页面响应速度。
节流(Throttling)是一种前端开发中常用的技术,用于控制函数的执行频率。与防抖不同,节流是确保函数在一定时间内最多只执行一次,而不是在时间内只执行一次。换句话说,函数在设定的时间间隔内最多执行一次,无论它被调用了多少次。
节流的实现方式通常是使用定时器。当函数被调用时,先检查当前是否已经存在定时器,如果存在,则不执行函数;如果不存在,则设置一个定时器,在定时器到达时执行函数。这样可以确保函数不会在短时间内被频繁执行,从而减轻性能压力。
节流的应用场景包括滚动事件、拖拽事件、鼠标移动等需要限制执行频率的操作。通过节流,可以平滑地控制这些事件的触发频率,避免不必要的计算和操作,提高页面性能和用户体验。
节流(Throttle
)和防抖(Debounce
)对于前端开发人员来说应该是十分熟悉的,节流(Throttle
)和防抖(Debounce
)是两种可以节省性能的编程技术,两者的目的都是为了优化性能,提高用户体验,都是基于 DOM 事件限制正在执行的 JavaScript 数量的方法。但两者的有什么不一样呢?
节流会强制执行一个函数在一段时间内可以被调用的最大次数。如“最多每 100 毫秒执行一次此函数”。
假设在正常情况下,会在 10
秒内调用此函数 1,000
次。如果将其限制为每 100
毫秒仅一次,则该函数最多只会执行 100
次。
(10s * 1,000)
= 10,000 ms
10,000 ms / 100 ms
限制 = 100
个最大调用防抖强制一个函数在一段时间内没有被调用之前不会被再次调用。如“仅当 100 毫秒过去了而没有被调用时才执行此函数”。
也许一个函数在短时间内被调用 1000
次,分散在3秒内,然后停止调用。如果在 100
毫秒的时间内启动,这个功能只会在 3.1
秒的时间内启动一次。每次在突发事件期间调用该函数时,它都会重置恢复计时器。
这些概念的一个主要用例是某些 DOM
事件,例如滚动和调整大小。例如,如果将滚动处理程序附加到一个元素,并将该元素向下滚动 5000
像素,可能会看到 100
多个事件被触发。如果事件处理程序做了大量工作(例如繁重的计算和其他 DOM
操作),可能会看到性能问题(卡顿)。如果可以减少执行该处理程序的次数,而不会对经验造成太大影响,那么这可能是值得的。
AJAX
事件100ms
响应一次在Vue中,防抖和节流的基本原理都是利用定时器和函数的闭包来控制函数的执行频率。下面分别介绍防抖和节流在Vue中的基本原理:
在Vue中,可以通过以下代码实现简单的防抖:
javascriptCopy code// 防抖函数
function debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// 使用防抖函数
const debouncedFunction = debounce(myFunction, 300);
在Vue中,可以通过以下代码实现简单的节流:
javascriptCopy code// 节流函数
function throttle(func, delay) {
let timer;
return function (...args) {
if (!timer) {
func.apply(this, args);
timer = setTimeout(() => {
timer = null;
}, delay);
}
};
}
// 使用节流函数
const throttledFunction = throttle(myFunction, 300);
这些基本原理可以帮助理解在Vue中如何通过定时器和函数闭包实现防抖和节流,以及如何控制函数的执行频率。
npm install throttle-debounce --save
限制回调函数的执行频率
/**
* 节流(限制函数的执行频率)
* @param delay 延迟的时间
* @param noTrailing 在最后一次调用时是否执行 callback,true 不执行,false 执行
* @param callback 目标回调函数
* @param debounceMode
*/
throttle(delay, noTrailing, callback, debounceMode)
dobounceMode: 为 true 时,在被调用时,先执行 callback,在没有被调用时,在指定的延迟之后执行 clear,如果在clear 执行之前继续调用,会重置定时器;为 false 时,在被调用时,不会执行 callback,在指定的延迟之后执行 callback,如果在 callback 执行之前继续调用,会重置定时器
限制回掉函数的执行频率,但是不同于 debounce 的是,debounce 能保证在一系列调用的时间内,回调函数只执行一次
atBegin: 为 true 时,在被调用时,会马上执行 callback,如果在延迟时间之前继续调用,不会执行 callback;为 false 时,在被调用时,不会执行 callback,在延迟时间之后会执行 callback,如果在延迟时间之前继续调用,会重置定时器
Throttle
)场景$("body").on("scroll", _.throttle(function() {
// 处理逻辑
}, 100));
Debounce
)场景实际生活中,如百度搜索,输入文本后会出现下拉选择,这个过程一般绑定文本事件 keypress
。
下图描述了使用防抖(Debounce
)前状态的性能监控捕获,每次 keypress
引发事件时,它都会触发搜索引擎请求数据并将结果呈现在屏幕上。事实上,这些结果并没有被用户看到,因为它们已经被最新 keypress
事件的后续结果覆盖了,屏幕上仅呈现最新结果。
$(window).on("resize", _.debounce(function() {
// 处理逻辑
}, 100));
防抖函数和节流函数都包含两个主要参数:被控制的函数(通常称为目标函数)和时间间隔。下面对这两个参数进行解析:
javascriptCopy codefunction debounce(func, delay) {
let timer;
return function (...args) {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
// 使用防抖函数
const debouncedFunction = debounce(myFunction, 300);
javascriptCopy codefunction throttle(func, delay) {
let timer;
return function (...args) {
if (!timer) {
func.apply(this, args);
timer = setTimeout(() => {
timer = null;
}, delay);
}
};
}
// 使用节流函数
const throttledFunction = throttle(myFunction, 300);
这些参数允许你在使用防抖和节流时根据需要调整目标函数的执行频率和延迟时间,以满足特定的应用场景。
调整防抖和节流的时间间隔是根据实际需求和应用场景来确定的。时间间隔决定了在触发事件后多久执行一次目标函数。以下是如何调整防抖和节流的时间间隔:
在防抖函数中,时间间隔是通过设定的延迟时间(delay)来控制的。你可以通过修改 debounce
函数的调用,传入不同的延迟时间来调整防抖的时间间隔。
javascriptCopy code// 使用不同的延迟时间调整防抖的时间间隔
const debouncedFunction = debounce(myFunction, 500); // 延迟500毫秒
在节流函数中,时间间隔也是通过设定的延迟时间(delay)来控制的。你可以通过修改 throttle
函数的调用,传入不同的延迟时间来调整节流的时间间隔。
javascriptCopy code// 使用不同的延迟时间调整节流的时间间隔
const throttledFunction = throttle(myFunction, 1000); // 每隔1000毫秒执行一次
根据实际场景的需要,你可以灵活地选择不同的时间间隔。较短的时间间隔可以提高响应速度,但可能增加函数执行的频率;较长的时间间隔则可以减轻性能压力,但可能降低响应速度。根据具体要求和性能考虑,选择一个合适的时间间隔是很重要的。
防抖 vs.节流: 防抖和节流都有助于提高性能,但在不同场景下的选择取决于实际需求。防抖适用于一定时间内只需执行一次的场景,而节流适用于需要平滑控制执行频率的场景。
延迟时间: 调整防抖和节流的延迟时间是关键,过长的延迟可能导致用户感知到的延迟,而过短的延迟可能增加函数执行频率,影响性能。
避免滥用防抖和节流是非常重要的,以确保它们在实际应用中发挥正确的作用。以下是一些建议:
通过理解场景、合理设置延迟、测试性能以及建立清晰的文档和共识,可以确保防抖和节流在代码中得到正确的应用,提高性能并改善用户体验。