资讯专栏INFORMATION COLUMN

debouncing 与 throttling

zzir / 2137人阅读

摘要:一个使用场景某些浏览器事件可能会在短时间内高频触发,比如整窗口大小或滚动页面。这会导致非常严重的性能问题。实现与类似,接收两个参数,一个是需要截流的函数,另一个是函数执行间隔阈值。

一个使用场景:
某些浏览器事件可能会在短时间内高频触发,比如:整窗口大小或滚动页面。
如果给窗口滚动事件添加一个事件监听器,然后用户不停地快速滚动页面,那你的事件可能在短短数秒之内被触发数千次。这会导致非常严重的性能问题。
所以如果功能涉及滚动事件,窗口调整事件,或者键盘事件鼠标事件等,你可能需要警觉起来,是否有必要使用 debouncing 或者 throttling 来提高页面速度与性能。

Debouncing(防抖动) 概念

debouncing(防抖动)是解决上述问题的一个方案,它的做法是 限制下次函数调用之前必须等待的时间间隔,也就是说:强制一个函数在某个连续时间段内只执行一次,哪怕它本来会被调用多次。正确实现 debouncing 的方法是:将若干个函数调用合并为一次,只有在空闲时间大于或等于给定值的时候,才执行调用方法。

实现

简单的实现一个 debounce 方法,接收两个参数,一个是需要防抖动的函数 fn,另一个是延迟时间delay

funciton debouncing(fn, delay) {
    let timer; //定时器
    return function() { 
        // 保存函数调用时的上下文和参数,传递给 fn
        const context = this;
        const args = arguments;
        
        clearTimeout(timer);
        
        timer = setTimeout(function(){
            fn.apply(context, args);
        }, delay);
    }
}

debounce 的使用方法如下:

$(document).on("keyup", debounce(function(e) {
    // 代码
}, 250))
Throttling(节流阀) 概念

throttling(节流阀)则是另一种解决问题的方案,它的做法是固定一段时间内函数调用的频率,它与 debouncing 最大的不同之处在于,throttling 会保证至少调用一次。

实现

debounce 类似,接收两个参数,一个是需要截流的函数 fn, 另一个是函数执行间隔阈值 threshhold

function throttle(fn, threshhold) {
    let timer; //定时器
    let last; //记录上次时间
    threshhold || (threshhold = 250); //默认间隔为250ms    
    return function() {
        // 保存函数调用时的上下文和参数,传递给 fn
        var context = this;
        var args = arguments;
        
        let now = +new Date();
        
        // 如果上次调用距本次调用的时间间隔不够,则不执行 fn,并重新计时
        if(last && now < last + threshhold){
            clearTimeout(timer);
            
            // 保证在当前时间区间结束后,再执行一次 fn
            timer = setTimeout({
                last = now;
                fn.apply(context, args);
            }, threshhold);                
        } else {  //如果时间间隔够了,则立刻执行 fn
            last = now;
            fn.apply(context, args);
        }   
}

throttle使用方法如下:

$(document).on("mouvemove", throttle(function(e) {
    // 代码
}, 250))
总结

debouncing 和 throttling 的区别还是很明显的:前者把一段时间的多次调用合并成一次,后者把一段时间的多次调用减少为数次。下图的展示十分便于理解。

相关文章:
实例解析防抖动(Debouncing)和节流阀(Throttling)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/85231.html

相关文章

  • throttle函数debounce函数

    摘要:当函数被再次触发时,清除已设置的定时器,重新设置定时器。函数设置定时器,并根据传参配置决定是否在等待开始时执行函数。函数取消定时器,并重置内部参数。 throttle函数与debounce函数 有时候,我们会对一些触发频率较高的事件进行监听,如果在回调里执行高性能消耗的操作,反复触发时会使得性能消耗提高,浏览器卡顿,用户使用体验差。或者我们需要对触发的事件延迟执行回调,此时可以借助th...

    Prasanta 评论0 收藏0
  • JS throttledebounce的区别

    摘要:可以看下面的栗子这个图中图中每个小格大约,右边有原生事件与节流去抖插件的与事件。即如果有连续不断的触发,每执行一次,用在每隔一定间隔执行回调的场景。执行啦打印执行啦打印执行啦节流按照上面的说明,节流就是连续多次内的操作按照指定的间隔来执行。 一般在项目中我们会对input、scroll、resize等事件进行节流控制,防止事件过多触发,减少资源消耗;在vue的官网的例子中就有关于lod...

    wawor4827 评论0 收藏0
  • 浅谈throttle以及debounce的原理和实现

    摘要:浅谈以及的原理和实现背景日常开发中我们经常会遇到一些需要节流调用或者压缩调用次数的情况例如之前我在完成一个需求的时候就遇到了因为后端并发问题导致收到多条信息从而导致函数被重复调用的情况当时的做法是通过对函数的调用进行注册遇到多次调用的时候清 浅谈throttle以及debounce的原理和实现 背景 日常开发中,我们经常会遇到一些需要节流调用,或者压缩调用次数的情况,例如之前我在完成...

    jsbintask 评论0 收藏0
  • throttledebounce的区别

    摘要:自己尝试一下年在的文章中第一次看到的实现方法。这三种实现方法内部不同,但是接口几乎一致。如你所见,我们使用了参数,因为我们只对用户停止改变浏览器大小时最后一次事件感兴趣。 前几天看到一篇文章,我的公众号里也分享了《一次发现underscore源码bug的经历以及对学术界拿来主义的思考》具体文章详见,微信公众号:showImg(https://segmentfault.com/img/b...

    Pluser 评论0 收藏0
  • [译]通过实例讲解Debouncing和Throtting(防抖节流)

    摘要:译通过实例讲解和防抖与节流源码中推荐的文章,为了学习英语,翻译了一下原文链接作者本文来自一位伦敦前端工程师的技术投稿。首次或立即你可能发现防抖事件在等待触发事件执行,直到事件都结束后它才执行。 [译]通过实例讲解Debouncing和Throtting(防抖与节流) lodash源码中推荐的文章,为了学习(英语),翻译了一下~ 原文链接 作者:DAVID CORBACHO 本文来自一位...

    Jenny_Tong 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<