防抖与节流的理解与应用
前端防抖(Debounce)和节流(Throttle)都是用于控制函数执行频率的技术,主要应用于优化高频事件(如滚动、输入、窗口调整等)的性能表现。
一、防抖(Debounce)
原理:当事件被连续触发时,只有在事件停止触发后的指定时间间隔内没有再次触发,才会执行目标函数。
适用场景:
-
搜索框输入联想(等待用户停止输入后再请求)
-
窗口大小调整(等待调整结束后计算布局)
-
表单验证(输入停止后再验证)
实现示例(关键:clearTimeout
):
function debounce(func, delay) {let timer;return function(...args) {clearTimeout(timer);timer = setTimeout(() => {func.apply(this, args);}, delay);};
}// 使用
input.addEventListener('input', debounce(searchSuggestions, 300));
输入框防抖:
<input type="text" id="search" placeholder="请输入内容">
<script>
const input = document.getElementById('search');input.addEventListener('input', debounce((e) => {console.log('搜索内容:', e.target.value);
}, 500));
</script>
效果:用户输入停止 500ms 后,才触发 console.log。
二、节流(Throttle)
原理:在指定时间间隔内,无论事件触发多少次,目标函数最多执行一次。
适用场景:
-
页面滚动加载(固定间隔检查位置)
-
鼠标频繁点击(防止重复提交)
-
游戏中的射击按钮(限制射击频率)
实现示例(关键:时间戳判断):
function throttle(func, interval) {let lastTime = 0;return function(...args) {const now = Date.now();if (now - lastTime >= interval) {func.apply(this, args);lastTime = now;}};
}// 使用
window.addEventListener('scroll', throttle(handleScroll, 200));
滚动监听:
<div style="height: 2000px;"></div>
<script>
window.addEventListener('scroll', throttle(() => {console.log('滚动中...', new Date().toLocaleTimeString());
}, 1000));
</script>
效果:无论滚动多快,scroll 事件每秒最多执行一次。
核心区别对比
实际场景举例
-
搜索框联想词(防抖):
-
用户连续输入
a→ab→abc→abcd
,防抖会等到用户停止输入 300ms 后,才发送一次请求(请求abcd
)。 -
如果用节流,每隔
300ms
发送一次请求(可能发送a
、ab
、abcd
多次请求)。
-
-
窗口滚动加载(节流):
-
用户疯狂滚动页面,节流会每隔
200ms
检查一次滚动位置,避免频繁计算。 -
如果用防抖,只有停止滚动时才触发,用户持续滚动时可能永远不加载。
-
三、应用:使用 Lodash 库实现防抖和节流
Lodash 提供了现成的 debounce
和 throttle
函数,适用于快速集成到 Vue 3 项目中
1. 安装与引入
npm install lodash
import { debounce, throttle } from 'lodash';
2. 防抖示例(输入框搜索)
<template><input v-model="inputValue" @input="handleInput" />
</template><script setup>
import { ref } from 'vue';
import { debounce } from 'lodash';const inputValue = ref('');// 防抖处理输入事件(延迟 300ms 后触发)
const handleInput = debounce(() => {console.log('搜索内容:', inputValue.value);// 发送请求或处理业务逻辑
}, 300);
</script>
场景:用户连续输入时,仅在停止输入 300ms 后触发搜索,减少无效请求
3. 节流示例(滚动加载)
<template><div @scroll="handleScroll">滚动区域</div>
</template><script setup>
import { throttle } from 'lodash';// 节流处理滚动事件(每 200ms 最多触发一次)
const handleScroll = throttle(() => {console.log('检查滚动位置');// 加载更多数据
}, 200);
</script>
场景:滚动时固定频率检查位置,避免高频计算
注意事项
-
内存泄漏:在组件销毁时,需清除事件监听器和定时器(如
beforeUnmount
中移除)。 -
延迟时间选择:防抖时间过长会导致响应延迟,过短则失去优化意义;需根据场景权衡。