前言
在进行窗口调整(resize)、滚动(scroll)以及输入框内容校验等操作时,若事件处理函数频繁调用,可能会给浏览器带来极大负担,从而导致用户体验变差。为了优化性能,我们可以使用防抖(debounce)和节流(throttle)技术来控制函数的调用频率,从而提高应用的效率和流畅度。它们的核心思想是通过设置时间间隔来限制函数的执行时机。
防抖(Debounce)
防抖技术的关键在于:在一个事件被触发后,等待一段时间(n秒)再执行回调函数。如果在这段时间内该事件再次被触发,则重新计时。这样可以有效减少函数的执行次数,特别适用于高频次的事件,如用户输入或窗口调整。
示例代码
未使用防抖的效果
var mydiv = document.getElementById('mydiv');
let count = 0;
function myEvent() {
mydiv.innerText = count++;
}
mydiv.addEventListener('mouseover', function(event) {
myEvent();
});
使用防抖后的效果
function debounce(fn, delay) {
let timeout = null;
return function() {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
}
}
var mydiv = document.getElementById('mydiv');
let count = 0;
function myEvent() {
mydiv.innerText = count++;
}
mydiv.addEventListener('mouseover', debounce(myEvent, 2000));
原理说明
防抖的核心在于推迟函数的执行,直到事件触发停止一段时间后才执行回调。例如,在鼠标移动时,只有在最后一次触发事件后经过2秒钟才执行回调函数 myEvent
。如果用户持续移动鼠标,函数会在最后一次移动后再等待2秒才执行。这种方式有效避免了高频事件的频繁处理,减少了对浏览器性能的影响。
节流(Throttle)
节流技术的关键在于:在一定时间间隔(delay)内,只允许函数执行一次,即使该时间间隔内事件被多次触发,也仅有第一次生效。节流可以有效降低函数执行频率,使事件处理更为稳定。
示例代码
定时器实现方式
function throttle(fn, delay) {
let hasRun = false;
return function() {
if (hasRun) {
return;
}
hasRun = true;
setTimeout(() => {
hasRun = false;
fn.apply(this, arguments);
}, delay);
}
}
var mydiv = document.getElementById('mydiv');
let count = 0;
function myEvent() {
mydiv.innerText = count++;
}
mydiv.addEventListener('mouseover', throttle(myEvent, 2000));
时间戳实现方式
let div = document.querySelector('div');
var count = 0;
function myEvent() {
div.innerText = count++;
}
div.onmouseover = throttle(myEvent, 2000);
function throttle(func, wait) {
let pre = 0;
return function() {
let now = new Date().getTime();
if (now - pre > wait) {
pre = now;
func.apply(this);
}
}
}
原理说明
节流的核心在于限制函数的执行频率。无论事件触发的频率如何,函数将在每个时间间隔(delay)内只执行一次。例如,当鼠标持续移动时,回调函数 myEvent
每隔2000毫秒执行一次,这样可以有效控制函数的调用频率,减轻浏览器的负担。
应用场景
防抖应用场景
- 搜索联想:在用户输入搜索内容时,使用防抖来减少请求次数,提高搜索效率。
- 窗口调整:在窗口大小调整过程中,使用防抖来避免频繁触发事件,优化性能。
- 防止重复提交:在用户提交表单时,使用防抖来防止重复提交操作。
节流应用场景
- 鼠标点击:在鼠标快速点击时,使用节流来限制处理次数,避免过度触发事件。
- 滚动事件:在监听滚动事件时,例如判断是否滑动到底部自动加载更多内容,使用节流来控制事件触发频率。
通过合理运用防抖和节流技术,可以有效提升用户体验,同时优化浏览器性能。