JavaScript中的节流与防抖函数记不住?我的答案保你终身难忘【一小时搞懂,建议收藏】

前端性能优化-防抖和节流

前言

防抖和节流严格算起来应该属于性能优化的知识,但实际上遇到的频率相当高,处理不当或者放任不管就容易引起浏览器卡死。所以还是很有必要早点掌握的。

据说阿里有一道面试题就是谈谈函数节流和函数防抖。

防抖(debounce)

函数防抖(debounce):当持续触发事件时,在设置的周期内没有再触发事件,事件处理函数才会执行一次,如果设定的周期没有结束,又一次触发了事件,就重新开始延时。

为了有个直观的对比,我们先看下没有使用debounce技术的click事件:

我们看到,当用户频繁点击button按钮时,控制台会频繁的输出结果,这种频繁调用事件处理程序,会加重浏览器的负担,导致用户体验非常糟糕。

为了解决上述问题,我们在编码中可以使用debounce防抖技术。

防抖原理:是维护一个计时器,在规定的delay时间后触发函数,但是在delay时间内再次触发的话,就会取消之前的计时器而重新设置。这样一来,只有最后一次操作能被触发。

看一个🌰(栗子):

function debounce(fn, delay) {
  var timer = null;
  return function() {
     // 清除已存在的定时器
     timer && clearTimeout(timer)
     timer = setTimeout(function() {
        fn.apply(this)
     }, delay)
  }
}
let $btn = document.getElementById('btn');
var fn = function() {
  console.log ('防抖旨在时间段内只触发最后一次执行' + new Date(Date.now()));
}
$btn.onclick = debounce(fn, 1000);

如图,持续触发click事件时,并不会每次触发都会执行事件处理函数,当在设置的周期1000 ms内没有再触发click事件时,才会延时触发click事件。

节流(throttle)

函数节流(throttle):函数执行一次后,只有在大于设置的执行周期后才会执行第二次。持续触发事件时,保证一定时间段内只调用一次事件处理函数。

throttle翻译为节流阀,我们可以想象成我们水龙头放水,阀门一打开,水哗哗的往下流,秉着勤俭节约的优良传统美德,我们要把水龙头关小点,最好是如我们心意按照一定规律在某个时间间隔内一滴一滴的往下滴。

同样我们先看一个没有使用throttle技术的scroll事件,如下图:

这种频繁的scroll操作都会给浏览器带来沉重的负担,接下来我们看下如何使用throttle技术。

节流原理:是记录上次执行的时间戳lastTime,每次触发事件时记录当前执行的时间戳nowTime,然后判断nowTime与lastTime的差值是否大于设定的周期delay,如果大于,则执行回调,并更新上次执行的时间戳,从而循环。持续触发事件时,保证一定时间段内触发事件处理函数的频率。

再看一个🌰:

function throttle(fn, delay) {
  // 记录上次触发的时间戳
  var lastTime = 0;
  return function() {
     // 记录当前触发的时间戳
     var nowTime = Date.now();
     // 如果当前触发与上次触发的时间差值 大于 设置的周期则允许执行
     if (nowTime - lastTime > delay) {
        fn.call(this);
        // 更新时间戳
        lastTime = nowTime;
     }
  }
}
document.onscroll = function () {
  console.log ('节流旨在时间段内控制触发的频率'+new Date(Date.now()))
}

如下图,持续触发scroll事件时,并不立即执行处理函数,当当前触发与上次触发的时间差值大于设置的周期时才会执行。

应用场景

上面介绍了防抖(debounce)节流(throttle) 的原理和实现方式。

下面简单列出两者的应用场景都有哪些:

防抖(debounce)应用场景:

  • 每个调整大小/滚动都会触发统计事件。
  • 验证文本输入(在连续文本输入后,发送Ajax请求进行验证)。
  • 监视滚动scroll事件(在添加去抖动后滚动,只有在用户停止滚动后才会确定它是否已到达页面底部)。

节流(throttle)应用场景:

  • 实现DOM元素的拖放功能mousemove。
  • 搜索关联keyup。
  • 计算鼠标移动距离mousemove。
  • 画布模拟草图功能mousemove。
  • 射击游戏中的 mousedown/keydown事件(每单位时间只能发射一颗- 子弹)。
  • 监视滚动scroll事件(添加节流后,只要滚动页面,就会每隔一段时间才会计算)。

总结

  • 函数防抖和函数节流都是防止某一时间频繁触发,但是这两兄弟之间的原理却不一样。
  • 函数防抖是某一段时间内只执行一次,而函数节流是间隔时间执行。

往期推荐

高频JavaScript面试题汇总

✍话题

什么样的答案终身难忘?学生时代关于记忆经常能听见两种论调:
1.死记硬背:见效快,但也忘得快,且一般不会灵活运用(指标不治本)
2.理解性记忆:见效慢,但记忆持久且会灵活运用(治标又治本)

如果是你,你愿意pick哪种?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容

  • 一、前言 相信无论在实际应用场景、亦或是面试,都会经常遇得到函数防抖、函数节流等,下面我们来聊一聊吧。 先放出一个...
    越前君阅读 912评论 0 15
  • 摘要:JavaScript 中的函数防抖和节流是很常用的需求,前端面试也是频率比较高被问到的知识,本文就通过二者的...
    EnochQin阅读 1,240评论 0 5
  • 防抖:就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。(常见...
    半日闲_balance阅读 203评论 0 0
  • 一、背景 防抖和节流是两种不同的控制一个函数执行次数的方法,其目的都是为了节约计算机资源。当我们操作DOM的时候,...
    HalShaw阅读 772评论 0 0
  • 表情是什么,我认为表情就是表现出来的情绪。表情可以传达很多信息。高兴了当然就笑了,难过就哭了。两者是相互影响密不可...
    Persistenc_6aea阅读 124,553评论 2 7