性能优化之防抖|节流
防抖(debounce)
定义:
- 防抖:单位时间内,频繁触发事件,只执行最后一次。
使用场景:
- 搜索框搜索输入。只需用户最后一次输入完,在发送请求
- 手机号,邮箱验证输入检测
案例1:
要求:鼠标在盒子上移动,数字+1
const box=document.querySelector('.box')
let i=1
function mouseMove(){
box.innerHTML=i++
// 如果代码中存在大量消耗性能的代码,dom操作或数据处理,就有可能造成卡顿
}
box.addEventListener('mousemove',mouseMove)
改进:利用防抖来处理,鼠标在盒子上移动,鼠标停止500ms之后,里面的数字+1
实现方式:
- lodash提供的防抖来处理
- 手写一个防抖函数来处理
lodash库实现:
<script src="https://cdn.bootcss.com/lodash.js/4.17.15/lodash.min.js"></script>
// 使用lodash库来实现防抖
// 语法:_.debounce(fun,时间)
box.addEventListener('mousemove',_.debounce(mouseMove,500))
手写防抖函数实现:
核心思路:
防抖的核心就是利用定时器(setTimeout)来实现
- 声明一个定时器变量
- 鼠标每次滑动都先判断是否有定时器,有定时器就先清除以前的定时器
- 如果没有定时器就开启定时器,并存到变量中
- 在定时器中调用要执行的函数
// 手写防抖函数
function debounce(fn,t){
let timer
return function(){
if(timer) clearTimeout(timer)
timer=setTimeout(function(){
fn()
},t)
}
}
box.addEventListener('mousemove',debounce(mouseMove,500))
节流(throttle)
定义:
- 节流:单位时间内,频繁触发事件,只执行一次。
举个例子
王者荣耀技能冷却,期间无法继续释放技能。触发事件时,若上一个任务还在,则取消触发。(防抖类似于回城)
使用场景
- 高频事件:鼠标移动mousemove、页面尺寸缩放resize、滚动条滚动scroll等等
案例2:
利用节流来处理,鼠标在盒子上移动,不管移动多少次,每隔500ms数字+1
实现方式:
- lodash提供的防抖来处理
- 手写一个节流函数来处理
lodash库实现:
box.addEventListener('mousemove',_.throttle(mouseMove,500))
手写节流函数实现:
核心思路:
节流的核心就是利用定时器(setTimeout)来实现
- 声明一个定时器变量
- 鼠标每次滑动都先判断是否有定时器,有定时器则不开启新的定时器
- 如果没有定时器就开启定时器,并存到变量中
- 在定时器中调用要执行的函数,并且要把定时器清空
function throttle(fn,t){
let timer=null
return function(){
if(!timer){
timer=setTimeout(function(){
fn()
// 在setTimeout中是无法删除定时器的,所以使用timer=null而不是clearTimeout(timer)
timer=null
},t)
}
}
}
box.addEventListener('mousemove',throttle(mouseMove,500))