一、对防抖和节流的理解
防抖和节流是两种可以节省性能的编程技术,目的都是为了优化性能,能减少搜索引擎的损耗,防止出现页面堵塞卡顿现象,提高用户体验。
什么是防抖(Debounce)
一段时间内,事件在我们规定的间隔 n
秒内多次执行,回调只会执行一次。
防抖函数的作用是控制函数在一定时间内的执行次数。简单点说就是通过防抖函数让某个触发事件在 n
秒内只会被执行一次
什么是节流(Throttle)
一段时间内,事件在每次到达我们规定的间隔 n
秒时触发一次。
节流函数的作用是在一个单位时间内最多只能触发一次函数执行,如果这个单位时间内多次触发函数,只能有一次生效。
二、防抖函数的应用场景
- 输入框实时搜索:当用户需要在搜索框内进行实时搜索,使用防抖函数可以延迟搜索请求的发送,只在用户停止输入一段时间后才真正发起请求,避免频繁的请求操作。
- 表单输入验证:在表单输入过程中,每次用户输入都可能触发验证操作。使用房否函数可以延迟搜索请求的发送,只在用户输入完毕一段时间后进行验证,避免频繁的验证操作。
三、节流函数的应用场景
- 页面滚动事件:当用户滚动页面时,会频繁触发滚动事件。使用节流函数可以控制滚动事件的触发频率,避免过多的计算和渲染操作,提高页面的性能和流畅度。
- 频繁点击按钮提交:在某些场景下,点击按钮可能会触发重复的提交操作。使用节流函数可以限制按钮点击的触发频率,防止重复的提交
四、实现手写防抖和节流函数
防抖函数
<div class="box">
<input type="text" id="demo">
</div>
<script>
function req(value){
console.warn("request: " + value + ", time: " + new Date());
}
const inputBox = document.getElementById("demo");
inputBox.addEventListener("keyup",e=>{
// req(e.target.value); //未进行防抖处理,
debounce(()=>req(e.target.value),500) //进行了防抖处理
})
// 防抖函数
/**
* @desc 防抖函数:一定时间内,只有最后一次操作,再过wait毫秒后才执行函数
* @param {Function} func 函数
* @param {Number} wait 延迟执行毫秒数
* @param {Boolean} immediate true 表示立即执行,false 表示非立即执行
*/
let timeout
function debounce(func, wait = 500, immediate = false) {
// 清除定时器
if (timeout) clearTimeout(timeout)
// 立即执行,此类情况一般用不到
if (immediate) {
let callNow = !timeout
timeout = setTimeout(() => {
timeout = null
}, wait)
if (callNow) typeof func === 'function' && func()
} else {
// 设置定时器,当最后一次操作后,timeout不会再被清除,所以在延时wait毫秒后执行func回调方法
timeout = setTimeout(() => {
typeof func === 'function' && func()
}, wait)
}
}
</script>
节流函数
<button id="demo" style="margin: 50px;">点击按钮</button></button>
<script>
let value = 1
function req(){
console.warn("request: " + value++ + ", time: " + new Date());
}
const ele = document.getElementById("demo");
ele.addEventListener("click", (e) => {
// req();//未使用节流函数
throttle(() => req(), 2000) //使用了节流函数,2秒内执行一次
});
/**
* @desc 节流函数:在一定时间内,只能触发一次
* @param {Function} func 函数
* @param {Number} wait 延迟执行毫秒数
*/
let previous = 0
function throttle(func, wait = 500) {
let now = Date.now()
if (now - previous > wait) {
typeof func === 'function' && func()
previous = now
}
}
</script>
五、总结
两种方式根据不同的场景选择使用,都能达到节省性能的效果。