防抖(Debounce)和节流(Throttle)是前端开发中常用的性能优化技术,尤其在处理高频事件时,比如窗口大小调整、滚动、键盘输入等。它们都旨在减少事件触发的频率,以提高性能和用户体验。
防抖(Debounce)
原理
防抖的原理是将多次执行合并为一次。具体来说,当事件被频繁触发时,防抖函数会在每次事件触发后延迟执行,只有在延迟时间内没有再次触发事件时,才会真正执行事件处理函数。
实现
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
应用场景
- 输入框联想搜索:在用户输入停止后进行搜索,而不是每次输入字符都进行搜索。
- 窗口大小调整:在用户停止调整窗口大小后再执行调整后的操作。
实例
防抖:创建一个防抖项目,其中目录包括前端和后端,后端JSON Server模拟网页从数据库中拿数据的过程,前端写一个html页面输入框模拟用户输入自己账号名字提示从数据库中拿值出来
npm run dev把json-server跑起来 端口号3000
自己创建用户表
前端代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div>
没有防抖的input
<input type="text"
id = "unDebounce"
placeholder="请输入用户名">
</div>
<div>
防抖的input
<input type="text"
id = "debounce"
placeholder="请输入用户名">
</div>
<script>
//不加防抖的
const inputa = document.getElementById('unDebounce');
const inputb = document.getElementById('debounce');
function handleNameSearch(e) {
// console.log(e.target.value)
const value = e.target.value;
fetch('http://localhost:3000/users')
.then(res => res.json())
.then(data =>{
// console.log(data)
const users = data;
const filterUsers = users.filter(user => {
//数组上的新方法 map转换 filter过滤
//callback回调函数
return user.name.includes(value)//es6中新方法,可读性好
// return user.name.indexOf(value) !== -1//可读性差
})
console.log(filterUsers)
})
}
//闭包
function debounce(func,delay){
//返回值必须得是函数 keyup 事件处理函数
//let id;
return function(args){
clearTimeout(func.id)//清除定时器
//函数是一个对象, id 挂在func上 func是闭包中的自由变量
func.id = setTimeout(function(){
func(args)
},delay)
}
}
const debounceNameSearch = debounce(handleNameSearch, 500)//闭包功能函数
//减少服务器端的压力,0.5秒
inputa.addEventListener('keyup',handleNameSearch)
inputb.addEventListener('keyup',debounceNameSearch)
</script>
</body>
</html>
事件event
- keyup 快速找到你想要的数据
猜你喜欢
ajaxSuggest
googleSuggest ,最早google发明
- ajax 向服务器请求数据
动态修改页面的能力
- 服务器的能力
- 并发
- 总连接数是有上限的
- CPU / 内存
效果展示
没有加防抖,在每次输入字符时都进行搜索
加了防抖,只有键盘输入停止设置的时间才会返回最后一次搜索
优点
- 减少不必要的函数执行,降低性能开销。
- 提升用户体验,使应用反应更加灵敏和直观。
节流(Throttle)
原理
节流的原理是限制函数的执行频率。具体来说,节流函数会在一定时间间隔内只执行一次事件处理函数,即使事件被多次触发。
实现
function throttle(func, wait) {
let lastTime = 0;
return function(...args) {
const now = Date.now();
if (now - lastTime >= wait) {
lastTime = now;
func.apply(this, args);
}
};
}
应用场景
- 滚动事件:限制滚动事件处理函数的执行频率,减少计算和渲染的次数。
- 按钮点击:防止按钮在短时间内被多次点击,导致多次提交或执行。
实例
节流
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>节流</title>
</head>
<body>
<div class="raw">
<div>
没有节流的input <input type="text" id="inputa">
</div>
<div>
有节流的input <input type="text" id="inputc">
</div>
</div>
<script>
const inputa = document.getElementById('inputa');
const inputc = document.getElementById('inputc');
// 节流函数,限制函数的执行频率
const throttle = (func, delay) => {
let lastTime; // 记录上次函数执行的时间
let deferTimer; // 延迟执行的定时器
// 返回一个新的函数,这个函数在触发事件时会执行节流逻辑
return (...args) => {
const now = +new Date(); // 获取当前时间
if (lastTime && now < lastTime + delay) {
// 如果两次触发间隔小于delay,重置定时器
clearTimeout(deferTimer);
deferTimer = setTimeout(() => {
lastTime = now;
func(...args); // 延迟执行函数
}, delay);
} else {
lastTime = now; // 记录当前时间
func(...args); // 立即执行函数
}
};
};
// 模拟一个耗时的Ajax请求
const ajax = (content) => {
console.log(`ajax request ${content}`);
};
// 没有节流的输入框,输入时每次触发事件都会调用ajax
inputa.addEventListener('keyup', (e) => {
ajax(e.target.value);
});
// 创建一个节流函数,间隔为1000毫秒
const throttleFunc = throttle(ajax, 1000);
// 有节流的输入框,输入时会调用节流函数
inputc.addEventListener('keyup', (e) => {
throttleFunc(e.target.value);
});
</script>
</body>
</html>
效果
没有加节流:每一次输入都被敏锐的拿到,非常耗费性能
加了节流:在输入每间隔一段时间执行一次,提升性能
优点
- 控制事件处理函数的执行频率,保证在高频触发的情况下,函数能够在预定时间间隔内执行一次。
- 提升性能,减少不必要的资源消耗。
比较与选择
- 防抖:适合那些在高频率事件停止后才需要执行的场景,例如输入框的实时搜索。在这些场景中,防抖可以避免大量不必要的计算和网络请求。
- 节流:适合那些需要持续执行且需要限制执行频率的场景,例如滚动事件处理。在这些场景中,节流可以确保函数在规定的时间间隔内执行一次,从而降低对浏览器性能的影响。
性能优化与用户体验
-
性能优化:
- 防抖和节流可以显著减少高频事件的处理次数,从而降低CPU和内存的使用。
- 通过减少不必要的DOM操作和重绘重排,提高应用的整体性能。
-
用户体验:
- 防抖可以使用户输入等操作更加流畅,不会因为频繁的网络请求或计算而卡顿。
- 节流可以使滚动、拖拽等操作更加平滑,防止因为过多的事件处理导致卡顿。
总结来说,防抖和节流是提升前端性能和用户体验的重要手段。在实际开发中,应根据具体场景选择合适的方法,避免不必要的性能消耗和用户体验的下降。