节流(Throttle) 和 防抖(Debounce) 是两种常见的函数优化技术,通常用于控制高频率触发的事件(例如窗口缩放、滚动、输入等)。它们的目的都是为了提高性能,避免因频繁触发某些事件导致性能下降或其他问题。
一、节流(Throttle)
节流的原理 是让某个函数在一定时间间隔内只执行一次。即使在这个时间间隔内这个函数被多次调用,它也只会执行一次。可以形象地理解为:在规定时间内,无论触发多少次事件,函数只执行一次。
实现原理
- 记录上一次函数执行的时间戳。
- 每次触发事件时,比较当前时间和上一次执行的时间,如果超过了设定的时间间隔,就执行函数并更新时间戳。
适用的业务场景
- 窗口的
resize
事件:调整窗口大小时频繁触发,可以使用节流来控制执行频率。 - 页面滚动
scroll
事件:用户滚动页面时频繁触发,可以使用节流来减少事件处理的次数。 - 按钮点击事件:防止用户频繁点击按钮导致的重复提交。
代码示例
function throttle(func, delay) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= delay) {
lastTime = now;
func.apply(this, args);
}
};
}
const handleResize = throttle((event, customParam) => {
console.log('窗口大小改变,参数:', customParam);
}, 500);
window.addEventListener('resize', (event) => handleResize(event, '参数传递'));
二、防抖(Debounce)
防抖的原理 是让某个函数在某段时间内没有被再次触发时才执行。即如果在这段时间内函数被再次调用了,则重新计时。可以形象地理解为:等用户的输入或操作稳定后再执行某个函数。
实现原理
- 每次事件触发时,清除之前的延迟调用。
- 重新设置一个新的延迟调用。
适用的业务场景
- 搜索框输入:用户输入时频繁触发搜索查询,可以使用防抖来减少查询次数,只在用户停止输入一段时间后再进行查询。
- 表单验证:用户输入表单时,实时验证可以使用防抖来减少验证次数。
- 窗口的 resize 事件:调整窗口大小后,稳定一段时间再做处理。
代码示例
<template>
<el-input v-model="value" @input="handleSearch"></el-input>
</template>
function debounce(func, delay) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
const handleSearch = debounce((val) => {
console.log('搜索查询,参数:',val);
}, 500);
三、总结
1. 执行频率
- 节流:在规定时间内无论触发多少次,函数只执行一次。
- 防抖:在规定时间内如果有多次触发,函数只会在最后一次触发后的延迟时间内执行。
2. 应用场景
- 节流:适用于需要限制函数执行频率的场景,如鼠标拖拽、滚动条、窗口调整等,需要在持续触发过程中定期执行的场景。
- 防抖:适用于需要在一定时间内不重复执行函数的场景,如搜索框输入、表单验证等,需要在用户停止操作后再执行的场景。
3. 实现原理
- 节流:通过记录上一次执行时间和当前时间的差值,来决定是否执行函数。
- 防抖:通过设置和清除定时器来控制函数的执行时机。
节流 用于控制函数的执行频率,确保在一定时间间隔内只执行一次。
防抖 用于确保函数在一段时间内的连续触发仅在最后一次触发后执行。