js性能优化之防抖与节流
js防抖与节流
案例准备
需求:鼠标在盒子上移动,里面的数字就会变化+1
实现代码:
//css 样式
<style>
.box {
width: 300px;
height: 300px;
line-height: 300px;
font-size: 50px;
text-align: center;
background-color: #f5eded;
margin: 0 auto;
}
</style>
//html 结构
<div class="box"></div>
//js
<script>
const box = document.querySelector('.box')
let i = 0
function mouseMove() {
box.innerHTML = i++
//如果这个函数里面存在大量消耗性能的代码 比如dom操作 数据处理 可能造成卡顿
}
box.addEventListener('mousemove', mouseMove)
<script>
由于事件触发过于频繁 有性能问题 所以 通过防抖和节流来对性能进行优化
鼠标一上去就加到66了 恐怖
一 防抖(Debounce)
1 什么是防抖?
举个栗子
进电梯 进电梯之后假如门3s关闭 如果这3s内又有人进来了 就又会等3s再关门 之前关门的行为就消失了 又要重新等3s再关门 如果这3s又有人进来 就还得在等3s
上概念
单位时间内 频繁触发事件 只执行最后一次
也就是 做一件事 不是立即就做 而是等一段时间后再做 如果在这个时间内又触发了事件 就在等一段时间 只执行最后一次 这就是函数防抖
2 防抖应用场景
比如说搜索框 搜索输入 只需用户最后一次输入完 才发送请求
手机号,邮箱输入表单验证 输入检测
3 需求及实现方式
(1)需求
鼠标在盒子上移动 鼠标停止500ms后 里面的数字才会变化+1
(2)lodashi提供的防抖函数来处理
官方地址: lodashi
使用lodash之前先引入(我这里直接cdn引入了)
<script src="https://cdn.bootcss.com/lodash.js/4.17.15/lodash.min.js"></script>
box.addEventListener('mousemove', _.debounce(mouseMove, [wait = 500]))
(3)手写一个防抖
防抖的核心就是setTimeout来实现
实现步骤:
1 声明一个定时器变量
2 当鼠标每次滑动(事件触发)都先判断是否有定时器了,如果有定时器先清除以前的定时器
3 如果没有定时器则开启定时器,记得存到变量里面
4 在定时器里执行调用的函数
function debounce(fn, t) {
let timer
return function () {
if (timer) clearTimeout(timer)
timer = setTimeout(() => {
fn()
}, t)
}
}
box.addEventListener('mousemove', debounce(mouseMove, 500))
二 节流(Throttling)
1 什么是节流?
举个栗子
王者荣耀 技能冷却 冷却期间触发技能 不会释放技能
上概念
单位时间内 频繁触发事件 只执行一次 也就是做一件事完成需要3s 在这3s内 无论你触发几次 都不会执行 等3s完执行后 你在触发 才会执行
2 节流应用场景
高频事件 :鼠标移动 mousemove,页面尺寸缩放resize,滚动条scroll等等
3 需求及实现方式
(1)需求
鼠标在盒子上移动 不管移动多少次 每隔500ms 才+1
(2)当然还是我们的lodash
官方地址: lodashi
使用lodash之前先引入(我这里直接cdn引入了)
<script src="https://cdn.bootcss.com/lodash.js/4.17.15/lodash.min.js"></script>
box.addEventListener('mousemove', _.throttle(mouseMove, [wait = 500]))
(3)来吧 展示 上代码
节流的核心也是setTimeout来实现
实现步骤:
1 声明一个定时器变量
2 当鼠标每次滑动(事件触发)都先判断是否有定时器了,如果有则不开启新的定时器
3 如果没有定时器则开启定时器,记得存到变量里面
4 在定时器里执行调用的函数 定时器里面要把定时器清空
function throttle(fn, t) {
let timer = null
return function () {
if (!timer) {
timer = setTimeout(() => {
fn()
timer = null
}, t)
}
}
}
box.addEventListener('mousemove', throttle(mouseMove, 500))