前端性能优化:深入理解防抖与节流
一、 什么是防抖?
核心思想:在事件被触发n秒后执行回调,如果在这n秒内又被触发,则重新计时。
通俗理解:好比坐电梯,电梯门等待5秒后自动关闭。如果期间有人进来(再次触发),电梯门会重新等待5秒。直到没有人再进来,电梯门才会最终关闭(执行函数)。
典型场景:
搜索框联想:用户停止输入500毫秒后,才发送请求。
窗口resize:窗口调整停止后,才进行DOM计算。
代码实现:
javascript
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
// 使用示例
const myInput = document.getElementById('search');
const sendRequest = () => { console.log('发送搜索请求...'); };
myInput.addEventListener('input', debounce(sendRequest, 500));
二、 什么是节流?
核心思想:在一个单位时间内,无论事件触发多少次,只执行一次函数。
通俗理解:好比地铁,每隔5分钟发出一班。无论这5分钟内来了多少乘客,都只会在5分钟时间点到的时候发车。
典型场景:
滚动加载(scroll):每隔1秒计算一次位置,而不是每次滚动都计算。
按钮点击(click):防止用户重复提交,2秒内只生效一次。
鼠标移动(mousemove):拖拽元素时,限制更新位置的频率。
代码实现:
javascript
function throttle(func, limit) {
let inThrottle;
return function(...args) {
if (!inThrottle) {
func.apply(this, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
}
// 使用示例
window.addEventListener('scroll', throttle(() => {
console.log('计算滚动位置,判断是否加载更多...');
}, 1000));
三、 核心区别与选择策略
为了更直观地理解它们的区别,我们可以看一个比喻:
特性 防抖 节流
核心目标 只在最后执行一次 有规律地执行
执行时机 连续触发结束后,等待wait后执行 在连续触发期间,每隔limit时间执行一次
类比 回城:每次被打断都要重新读条 普攻:有固定的攻击间隔,无法取消
如何选择?
关心结果,不关心过程?用防抖。
比如搜索:我们只关心用户最终输入了什么,不关心他中间修改了多少次。
关心过程,需要均匀执行?用节流。
比如滚动加载:我们需要在用户滚动过程中,定期检查是否到了底部。
四、 使用 Lodash 库
在实际项目中,我们不必重复造轮子。著名的工具库 Lodash 提供了非常完善且健壮的 _.debounce 和 _.throttle 函数,直接使用是更好的选择。
bash
npm install lodash
javascript
import { debounce, throttle } from 'lodash';
// 使用方式与上面类似,但功能更强大(例如 leading/trailing 选项)
const debouncedFn = debounce(sendRequest, 500);
const throttledFn = throttle(handleScroll, 1000);

浙公网安备 33010602011771号