去抖动与节流
在本文中,我们将讨论去抖动和节流到底是什么,我们为什么要使用它们以及两者之间的主要区别。
网页中可能存在一些需要耗时计算的功能。由于 JavaScript 是单线程语言,如果频繁调用此类方法,可能会严重影响浏览器的性能。为了避免这种情况,我们使用了去抖动和节流的概念。这两种技术都用于性能优化和限制某些函数调用的速率。
现在我们将通过一个简单的例子深入探讨这些概念:
让我们举个例子,你需要在你的应用中实现一个建议性文本功能。根据用户输入,我们调用一个开销很大的函数(例如向后端发起 API 调用),并向用户提供建议。
情况 1:一般情况(无任何优化)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<input type="text" name="search" id="search" placeholder="Search">
<script src="index.js" type="text/javascript"></script>
</body>
</html>
//Case 1 : Without Optimization
let textField = document.querySelector('#search');
textField.addEventListener('input', () => {
console.count("search action without optimization!!")
})
在上面的代码片段中,我们将为 keypress 事件添加一个监听器。每次输入任何关键字时,它都会调用一个函数。
上述技术并不是最佳的,并且会导致不必要的函数调用,从而降低网页的性能。
首先,我们来检查一下,如果用户还在输入,我们真的需要进行函数调用吗?不需要。我们应该等到用户停止输入一段时间后再进行函数调用。
为了进一步优化它,我们将使用去抖动和节流。
现在让我们逐一探讨一下:
案例 2:去抖技术
在去抖动技术中,无论用户触发事件多少次,附加函数只会在用户停止触发事件后的指定时间后执行。
让我们进一步修改你的js代码:
//Case 2: With Debouncing
const debounce = (func, delay) => {
let timerId;
return function () {
clearTimeout(timerId)
timerId = setTimeout(() => func.apply(this, arguments), delay)
};
};
function handleButtonClick() {
callbackFn();
}
function handleConsole() {
console.count("debounce function executed!!")
}
let callbackFn = debounce(handleConsole, 1000);
let textField = document.querySelector('#search');
textField.addEventListener('input', handleButtonClick);
debounce() 函数强制函数在再次运行之前等待一段时间。该函数旨在限制函数的调用次数。
正如您所注意到的,在上述场景中,函数调用的次数大幅减少,从而提高了我们的网络性能。
与第一种情况相比,在这种情况下,我们等待用户停止输入几秒钟后再调用我们的函数。因此,每次击键时,我们都会等待几秒钟后才给出建议。
案例三:节流技术
节流是一种技术,无论用户触发事件多少次,附加函数在给定的时间间隔内只会执行一次。
//Case 3: With Throttling
const throttle = (func, delay) => {
let toThrottle = false;
return function () {
if (!toThrottle) {
toThrottle = true;
func.apply(this, arguments)
setTimeout(() => {
toThrottle = false
}, delay);
}
};
};
function handleButtonClick() {
callbackFn();
}
function handleConsole() {
console.count("throttle function executed!!")
}
let callbackFn = throttle(handleConsole, 1000);
let textField = document.querySelector('#search');
textField.addEventListener('input', handleButtonClick);
节流用于每毫秒或特定时间间隔后调用一个函数,仅立即执行第一次点击。
throttle
函数采用现有的昂贵函数和延迟限制,并返回一个更好的昂贵函数,该函数仅在一定的延迟限制后调用。
在上面的场景中,如果用户继续输入,则除了第一个函数在用户开始输入时立即执行之外,其余所有函数都会在 1000 毫秒后执行。这可以防止函数的频繁调用。
但两者之间有什么区别呢??
防抖动和节流之间的区别
- 防抖功能会推迟执行,直到延迟时间内输入没有变化为止。如果发生变化,则取消先前安排的执行并创建新的计划。
- 如果标志为 false,则 Throttle 允许立即执行
toThrottle
。执行完成后,直到延迟时间结束才会调用此函数。
在去抖动 (debouncing) 中,只有当两次按键事件之间的时间差大于某个限制时,才会调用 API。
而在节流 (Throttling) 中,只有当两次函数调用之间的时间差大于某个限制时,才会调用 API。
应用:
- 在 Facebook 和 Twitter 等内容加载型网页中,用户会不断滚动页面。在这些情况下,如果滚动事件触发过于频繁,可能会对性能产生影响,因为其中包含大量视频和图片。
- 等到用户停止调整窗口大小
- 在用户停止输入之前不要触发 ajax 事件
- 测量页面滚动位置,最多每50ms响应一次
- 确保在应用程序中拖动元素时具有良好的性能
哪一个更好?
这完全取决于你应用这些概念的用例和场景。两者都是为了性能优化。
包起来!!
感谢您的时间!让我们一起学习,共同成长。
文章来源:https://dev.to/anuradha9712/debouncing-vs-throttle-lb2