防抖和节流概述
在前端开发中,防抖(Debounce)和节流(Throttle)是两种常用的性能优化策略
主要用于控制函数的执行频率,以避免在短时间内大量重复调用造成的性能问题,常应用于处理用户输入、窗口滚动、resize事件等场景。
防抖(Debounce)
防抖技术的核心思想是:当持续触发某个事件时,只在事件停止触发后的一定延迟时间后才执行一次回调函数。如果在这个延迟期内事件又被触发,则重新开始计时。这样可以确保最后一次操作结束后才执行回调,常用于搜索框的输入实时搜索、按钮防重复点击等场景。
例子:
function debounce(func, wait) {
let timeout;
return function() {
const context = this;
const args = arguments;
clearTimeout(timeout);
timeout = setTimeout(function() {
func.apply(context, args);
}, wait);
};
}
// 使用防抖函数
const debouncedSearch = debounce(function(query) {
// 实际的搜索逻辑
console.log('Searching for:', query);
}, 300);
// 假设这是用户输入触发的函数
inputElement.addEventListener('input', function(event) {
debouncedSearch(event.target.value);
});
节流(Throttle)
节流技术则是指限制一个函数在一定时间内只能执行一次,无论在这段时间内事件被触发了多少次。这种方式可以均匀地分配函数的执行频率,例如,让函数每秒最多执行一次,常用于窗口滚动事件处理、动画帧请求等场景。
例子:
function throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
}
// 使用节流函数
const throttledScrollHandler = throttle(function() {
// 实际的滚动处理逻辑
console.log('Handling scroll event');
}, 100);
// 假设这是窗口滚动事件
window.addEventListener('scroll', throttledScrollHandler);
总结
防抖:适合于减少连续的、频繁的操作引发的高频回调,比如搜索建议、表单验证等,确保最后一次操作后才执行。
节流:保证在规定的时间间隔内只执行一次函数,适合于控制行为的频率,如窗口滚动事件处理,确保行为在固定时间间隔内执行,而不是立即执行。
两者都能有效减少不必要的计算和渲染,提高应用性能和响应速度。选择使用哪种方法取决于具体的应用场景和需求。
在vue中配置
main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import i18n from '@/locale'
const on = Vue.prototype.$on
// 防抖
Vue.prototype.$on = function (event, func) {
let timer
let newFunc = func
if (event === 'click') {
newFunc = function () {
clearTimeout(timer)
timer = setTimeout(function () {
func.apply(this, arguments)
}, 500)
}
}
on.call(this, event, newFunc)
}
// 节流
Vue.prototype.$on = function (event, func) {
let previous = 0
let newFunc = func
if (event === 'click') {
newFunc = function () {
const now = new Date().getTime()
if (previous + 1000 <= now) {
func.apply(this, arguments)
previous = now
}
}
}
on.call(this, event, newFunc)
}
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
i18n,
store,
render: h => h(App)
})