防抖与节流
防抖与节流
第一次接触防抖与节流的概念是在一次面试中,但是当时并没有觉得防抖与节流很重要,知道后来学习vue做项目的时候才明白,防抖与节流能够有效地节省浏览器资源,因此更加深入地学习了防抖与节流的知识
函数防抖
当持续触发事件时,一定时间段内没有再触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发了事件,就重新开始延时。
在一个页面中我们会发现点击一次↓键会触发很多次scroll事件,如果我们在scroll事件中添加对是否显示回到顶部按钮条件的判定,那么这时会消耗大量的浏览器资源,做很多无用功,此时我们就需要防抖函数的出场了
我们提出这样一种设想: 当我们触发第一次scroll事件时启动一个延时函数,如果延时时间内再次触发了scroll事件,那么此时我们重新开始计时,直到延时时间内没有再次触发该事件然后再执行事件对应的函数
1 | function debounce(fn, deplay = 1000) { |
对于setTimeout()
,如果我们没有给deplay
进行赋值,将会赋予其默认值1000ms
简单修改之后,代码如下:
1 | function debounce(func, deplay) { |
适用场景:
- 表单提交场景:可以防止多次点击提交按钮,只执行最后一次的提交操作
- 服务端验证场景:如联想搜索,表单验证等,只执行最后一次输入后触发得到事件
节流
节流就是指连续触发事件,但是在n秒规定时间内只会执行一次函数
节流的使用虽然带来了很多便利,但是依旧有一些情况是防抖处理不了的,例如:当一个页面在浏览器中被打开,一个用户不断上下拖动进度条,此时我们
将永远不会执行scroll事件中的处理函数,因此我们需要使用另外一种策略,当用户第一次触发事件后一段时间内再次触发会失效,这也就是节流
1 | const throttle = (func, deplay = 500) => { |
代码解析: 当我们第一次触发事件时,flag=true
,此时将flag
设定为false
即锁定函数,开始计时执行处理函数,计时期间内再次触发事件时,flag = false
直接跳过所有步骤使本次触发失效
通过阅读文章我还找到了另外一种方法,使使用时间戳进行判定的
1 | const throttle = (func, deplay = 500) => { |
代码解析: 其实这个时间戳的版本也很好理解,每次触发事件获取一次现在的时间,如果与初次触发时间的差大于等待时间,那么执行函数,如果小于或等于即不执行
区别: 以上两种方法的区别就是,使用定时器会在延时以后执行函数,而时间戳方式是立即执行
试用场景:
- 拖拽场景:固定时间内只执行一次,防止超高频次触发位置变动
- 缩放场景:监控浏览器resize
- 动画场景:避免短时间内多次触发动画引起性能问题
- 部分后台系统表单中的快捷操作按钮