一、前言
前端开发中,“函数节流(throttle)” 和 “函数防抖(debounce)” 作为常用的性能优化方法,两者都是用于优化高频率执行 js 代码的手段,那具体它们有什么异同点呢?有对这两个概念不太了解的小伙伴,可以移步本人之前所写的 JS进阶篇1---函数节流(throttle) 和 JS进阶篇2---函数防抖(debounce)。
二、背景介绍
大家都知道,液晶显示器的屏幕刷新率通常为 60Hz ,即每秒屏幕内容刷新 60 次,那为什么是 60 次,而不是 30 次,或者 90 次呢?这是因为,当液晶显示器的屏幕刷新率为 60Hz 的时候(这里只讨论液晶显示器),人肉眼再也不能察觉出屏幕的闪烁现象,低于这个刷新频率画面会有卡顿现象,而高于这个频率的话,又会造成额外的资源和能源浪费,因此,液晶显示器的默认屏幕刷新率为 60Hz。
同理,在前端开发过程中,有一些会被高频触发的事件,例如 resize、scroll、mousemove 等,但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数,达到一定频率就足够了,因为超过这个频率之后,无论代码执行多少次,带来的效果也是一样,所以倒不如把 js 代码的执行次数控制在合理的范围。这样既可以节省计算机资源,又可以保证浏览的流畅性,这就是 “函数节流” 和 “函数防抖” 要解决的问题。
三、异同分析
相同点
实现:都可以通过使用 setTimeout 实现。
目的:都是为了降低回调函数执行频率,节省计算机资源,优化性能,提升用户体验。
本质:都是通过减少实际逻辑处理过程的执行来提高事件处理函数运行性能的手段,实质上并未减少事件触发次数。
不同点
1、概念不同
函数节流:一定时间内,控制 js 方法只执行一次。(例如:通常每隔一段时间,如 3s,人就会眨一次眼睛)。
函数防抖:事件频繁触发的情况下,只有经过足够的空闲时间,才执行代码一次。(举个栗子:乘坐电梯时,电梯只有检测到没有人进入,并经过一段时间之后(例如 10s),才会关闭电梯入口运行)。
2、实现方式不同
函数节流:声明一个变量当标志位,记录当前代码是否在执行。如果空闲,则可以正常触发方法执行。如果代码正在执行,则取消这次方法执行,直接 return。
函数防抖:需要一个 setTimeout 来辅助实现,延迟执行需要执行的代码。如果方法多次触发,则把上次记录的延迟执行代码用 clearTimeout 清掉,重新开始计时。如果在计时期间事件没有被重新触发,才执行代码一次。
3、要点不同
函数节流:函数节流的要点是,声明一个变量当标志位,记录当前代码是否在执行。
函数防抖:用 setTimeout 函数做缓存池,而且可以轻易地清除待执行的代码。
4、使用场景不同
“函数节流” 使用场景:
百度搜索框的输入联想功能
防止高频点击提交,防止表单重复提交
懒加载、加载更多、图片瀑布流或监听滚动条位置
“函数防抖” 使用场景
用户名、手机号、邮箱输入验证
搜索框输入关键字后,只需用户最后一次输入完,再发送请求
改变浏览器窗口大小时,只需窗口调整完成后,再执行 resize 事件中的函数,计算窗口大小,重新排布元素,防止重复渲染。
心得总结
不管是 “函数节流” 还是 “函数防抖”,都是用来进行性能优化的方式,也都是在项目开发过程中,为了解决开发中的实际问题而慢慢发展而来的,一定要在合适的场合才用正确的方法使用它们,切忌滥用,不然不仅不会发挥它们该有的作用,还会影响代码执行的正确性。有疑问或者建议,记得在评论区提出哦,欢迎留言!