一、什么是防抖节流: 💬
其本质是一种限制 高频执行代码
的手段
页面中常见的表单提交、短信验证码、搜索框、浏览器 resize
、 scroll
、 mousemove
等事件触发时,会不断的调用绑定在事件上的回调函数,影响前端性能,导致出现响应延迟
、假死
、卡顿
等现象。
因此需要对这类事件的调度进行限制,所以采用防抖(debounce)
和 节流(throttle)
方式来进行优化。
定义:
- 防抖:n 秒后执行一次,若在 n 秒内被重复触发,则重新计时;
- 节流:n 秒内只运行一次, 若在 n 秒内被重复触发,只生效一次;
区别:
- 防抖 侧重一定时间连续操作后,只在最后一次执行事件,应用于触发频率一般的场景;
- 节流 侧重一定时间连续操作中,每隔一段时间只执行一次,应用于触发频率较高场景;
二、应用场景:⛳️
- 防抖
- 搜索框搜索,待用户输入完,再进行检索
- 表单输入规范验证,如手机号、邮箱、密码等
- 表单提交
- 浏览器窗口 resize,待窗口调整完,计算窗口大小,防止重复渲染
- …
- 节流
- 数据滚动加载、加载更多、滚动到页面底部监听
- 搜索框 提示
- 高频点击事件
- …
三、函数实现(vue)💻
防抖
- 简易版
export function _debounce(func, delay) {
delay = delay || 500; // 设置默认延迟时间 .5s
let timer;
return () => {
let that = this;
let args = arguments; // 获取event对象
if(timer) clearTimeout(timer) // 若延迟已进行,清除延迟
timer = setTimeout(() => {
timer = null;
func.apply(that, args);
}, delay);
}
}
- 第一次立即执行,后续延迟执行
export function _debounce(func, delay, immediate) {
delay = delay || 500;
let timer;
return () => {
let that = this;
let args = arguments;
if(timer) clearTimeout(timer);
if(immediate) {
let callNow = !timer; // 第一次立即执行,后面延迟执行
timer = setTimeout(()=> {
timer = null
}, delay)
if(callNow) func.apply(that, args)
}else {
timer = setTimeout(() => {
func.apply(that, args)
}, delay)
}
}
}
节流
- 利用时间戳与定时器特性结合实现
export function _throttle(func, delay) {
delay = delay || 500
let timer = null;
let staTime = new Date();
return () => {
let curTime = new Date(); // 获取当前时间
let remTime = delay - (curTime - staTime); // 从上一次触发到现在,剩余的时间
let that = this;
let args = arguments;
clearTimeout(timer)
if(remTime <= 0) { // 剩余时间 <= 0,立即执行一次
func.apply(that, args)
staTime = new Date()
}else {
timer = setTimeout(func, remTime) // 剩余时间 > 0, 延迟到剩余时间后执行
}
}
}
调用
de:_debounce(function(){
console.log('~~2000ms')
},2000),
th:_throttle(function(){
console.log('~~2000ms')
},2000)
看完赶紧试试吧😏😏😏