javascript中的节流和防抖及应用场景

节流和防抖

当这两个概念放在一起时,就会显得有些绕,需要一些例子来帮助我们理解节流和防抖的原理究竟是什么,我们先摘出节流和防抖的字面定义。两者都是优化高频率执行js代码的一种手段。

节流概念:节制流入或流出,尤指用节流阀调节。在javascript中就是当某事件持续触发,保证一定时间内只对事件进行一次的处理。

防抖概念:与节流不同,节流是不让事件触发,切断事件触发,但是防抖是需要时间来进行判断触发,为什么?这就是防抖的定义:一个连续操作中的处理,只触发一次。如果不能理解,说的更简单点,我们需要时间,什么时间,在触发事件执行事件之间我们需要时间来判断,如果设定的时间到来之前,你又触发了一次事件,就重新开始延时,重新计算时间,一定时间内你没有进行同样的操作,那么时间一到就开始执行事件,这就是防抖。

下图帮助理解来自蒲公英tt

在这里插入图片描述
如图所示,其中delay=4,由于红色操作序列与绿色操作序列之间的时间间隔小于delay,所以这两个序列被视为一个连续操作行为。
debounceTail:执行操作在连续操作完成之后,触发;
debounceStart:执行操作在连续操作完成之前,触发;
throttle:在一个连续操作行为中,每间隔delay的时间触发1次。
结合运行图,可以更好的理解debounce、throttle的作用。
案例

节流(例如我们写轮播图中的开关):

  1. scroll 事件,每隔一秒计算一次位置信息
  2. 浏览器播放事件,每个一秒计算一次进度信息
  3. input 框实时搜索并发送请求展示下拉列表,没隔一秒发送一次请求 (也可做防抖)
  4. 对于键盘事件,当用户键入非常频繁,但我们又必须要在一定时间(阀值)内执行处理函数的时候。例如:一些网页游戏的键盘事件。
  5. 对于鼠标移动和窗口滚动,鼠标的移动和窗口的滚动会带来大量的事件,但是在一段时间内又必须看到页面的效果。例如:对于可以拖动的div,如果使用debounce,那么div会在拖动停止后突然跳到目标位置;这时就需要使用节流。

防抖(例如百度搜索):

  1. 登录、发短信等按钮避免用户点击太快,以致于发送了多次请求,需要防抖
  2. 调整浏览器窗口大小时,resize 次数过于频繁,造成计算过多,此时需要一次到位,就用到了防抖
  3. 文本编辑器实时保存,当无任何更改操作一秒后进行保存但是滑动条每次滑动都会触发出很多值变化,可以理解为每次滑动他都请求了好多次接口,这样就会影响性能。除此之外,还有scroll、mousemove等,也是会频繁触发,和这种情况类似。
  4. 稍微复杂一点的情况如搜索框input事件,支持实时搜索功能可使用节流方案,每隔一段时间就查询一下搜索内容;页面需要适配用到resize,可使用防抖方案。
  5. 对于键盘事件,当用户输入比较频繁的时候,可以通过防抖合并键盘事件处理。例如:需要在用户输入完成时进行字符串校验。
  6. 对于ajax请求的情况。例如:当页面下拉超过一定范围就通过ajax请求新的页面内容,这时候可以通过debounce合并ajax请求事件。(瀑布流)
 		let num=1;
        let content=document.getElementById('a');
        function count(){
            content.innerHTML=num++;
        };
       // content.addEventListener("mousemove",e=>count());

防抖

let time=0;
        let meter;
        function antiShake() {
            // timeout不为空,等待时间结束
            if(time!==0){
                console.log('时间还没有到,重新开始计时')
                // 清空计时器,重新开始计时
                clearTimeout(meter)
                meter = setTimeout(function clearTime() {
                    time=0;
                }, time);
            }else{
                // 立即执行加法
                count();
                time=1000;
                // 设置计数器
                meter=setTimeout(function clearTime() {
                    time=0;
                }, time);
            }
        }
        content.addEventListener("mousemove",e=>antiShake());

节流

let flag = true;
        function throttle(){
            if(!flag) return;
            flag=false;
            setTimeout(()=>{
                count();
                flag = true;
            },1000);
        }
        content.addEventListener("mousemove",e=>throttle());

总结

节流和防抖都是针对函数的:
1、节流:节流会稀释函数的执行频率。
节流的实现方式有两种可以选择:时间戳版和定时器版,区别就是,时间戳版的函数触发是在时间段内开始的时候,而定时器版的函数触发是在时间段内结束的时候。使得一定时间内只触发一次函数。原理是通过判断是否到达一定时间来触发函数。
2、防抖-----优化用户体验:适时反馈,避免UI渲染阻塞,浏览器卡顿,提升页面性能:避免页面渲染卡顿,减少服务器压力,防止恶意触发,防抖可以通过计时器来实现,通过setTimeout来指定一定时间后执行处理函数,如果在这之前事件再次触发,则清空计时器,重新计时。只有最后一次操作能被触发。
区别: 函数节流不管事件触发有多频繁,都会保证在规定时间内一定会执行一次真正的事件处理函数,而函数防抖只是在最后一次事件后才触发一次函数。 比如在页面的无限加载场景下,我们需要用户在滚动页面时,每隔一段时间发一次 Ajax 请求,而不是在用户停下滚动页面操作时才去请求数据。这样的场景,就适合用节流技术来实现。
“防抖是控制次数,节流是控制频率”!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MaxLoongLvs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值