文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

前端百题斩—通俗易懂的防抖与节流

2024-12-02 16:35

关注

性能一直是前端老生常谈的一个话题,其中有一个性能问题就是我们会频繁的触发一些事件,例如mousemove、scroll、resize等,虽然浏览器已经对这些事件的触发做了一些优化,但是如果在很短的时间内频繁的触发仍然会影响性能,这个时候就需要今天的主角:防抖和节流,利用它们来进行优化,提高性能。

1 防抖

1.1 定义

防抖就是将多次高频操作优化为只在最后一次执行(某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次)。通常的使用场景是:用户输入,只需在输入完成后做一次输入校验即可。

1.2 实现

防抖是将多次操作合并为一次操作完成,其原理就是维护一个计时器,在规定的时间后触发函数,但是在该规定时间内再次触发的话就会取消之前的定时器而重新设置,从而保证了只有最后一次操作能够被触发。其实现步骤如下所示:

  1. 利用闭包保存一个timer变量,然后返回一个函数(这个返回的函数就是后续频繁触发操作中调用的函数);
  2. 根据标志位判断是否第一次需要立即执行(因为有些情况是需要首次调用函数立即执行的,若没有该参数,就会在定时器到了之后才会执行);
  3. 当有新的触发时,若存在定时器,则清空该定时器;
  4. 设定一个新的定时器,重新计时。
  1. function debounce(fn, wait, immediate) { 
  2.         let timer = null
  3.         return function (...args) { 
  4.             // 立即执行的功能(timer为空表示首次触发) 
  5.             if (immediate && !timer) { 
  6.                 fn.apply(this, args); 
  7.             } 
  8.  
  9.             // 有新的触发,则把定时器清空 
  10.             timer && clearTimeout(timer); 
  11.             // 重新计时 
  12.             timer = setTimeout(() => { 
  13.                 fn.apply(this, args); 
  14.             }, wait); 
  15.         } 
  16.     } 

1.3 效果预览


观察效果图可以验证上述的理论知识:

  1. 防抖之后输出内容的频次降低了;
  2. 防抖之后,其在超过一定时间之后才会输出内容。

2 节流

2.1 定义

节流就是每隔一段时间后执行一次,也就是降低频率,将高频操作优化成低频操作。通常使用场景:滚动条事件、resize事件、动画等,通常每隔100-500ms执行一次即可。

2.2 实现

节流函数的实现方式有两种:定时器版本、时间戳版本,这两者各有千秋,下面来简要实现一下。

2.2.1 定时器版本

定时器版本的节流函数其重点是利用闭包保存timer变量,具有两个特点:

  1. n秒后才会执行第一次(定时器到了时间后才会触发);
  2. 停止触发后节流函数还会执行一次(因为该函数是延迟执行的,当停止触发时其任务已经到了队列中,所以停止后还会执行一次)。
  1. // 定时器版本 
  2. function throttle(fn, wait) { 
  3.     let timer = null
  4.     return function(...args) { 
  5.         if (!timer) { 
  6.             timer = setTimeout(() => { 
  7.                 fn.apply(this, args); 
  8.                 timer = null
  9.             }, wait) 
  10.         } 
  11.     } 

2.2.2 时间戳版本

时间戳版本的节流函数重点是利用闭包保存上一次的时间previous,具有两个特点:

开始触发后会立即执行(因为previous开始会被赋值为0);

停止触发后不再执行(因为该函数是同步任务,在触发的时候就会进行相应的判断,所以就不存在停止触发后再执行的情况)。

  1. // 时间戳版本 
  2. function throttle(fn, wait) { 
  3.     // 上一次执行时间 
  4.     let previous = 0; 
  5.     return function(...args) { 
  6.         // 当前时间 
  7.         let now = +new Date(); 
  8.         if (now - previous > wait) { 
  9.             previous = now; 
  10.             fn.apply(this, args); 
  11.         } 
  12.     } 

2.3 效果预览

观察效果图可以验证上述的理论知识:

  1. 节流确实降低了内容的输出频率,将高频变为低频;
  2. 时间戳版本的节流函数在首次会输出内容,但是最后一次的内容不会输出(谨慎使用);
  3. 定时器版本的节流函数确实不会立刻打印内容,而是超过一定时间之后才会打印;此外,其最后输入的内容会被打印出来。

 

来源:前端点线面内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯