前段时间接触到了 JS 中 防抖和节流 ,一开始还不明白他们的意思及应用场景,可后来才知道,这是前端中最基础的性能优化。
在绑定 scroll 、resize 这类事件时,当它发生时,它触发的频次非常高,间隔很近。如果事件中涉及到大量的 位置计算、DOM 操作、元素重绘 等工作且这些工作无法在下一个事件触发前完成,就会造成浏览器丢帧。
持续触发这类事件导致丢帧扩大、浏览器 CPU 使用率增加、用户体验受到影响。尤其是在涉及与后端的交互中,前端依赖于某种事件如resize,scroll,发送Http请求,在这个过程中,如果不做防抖处理,那么在事件触发的一瞬间,会有很多个请求发过去,增加了服务端的压力。
说了这么多介绍下什么是防抖和节流吧
防抖:在事件触发 n 秒后再执行回调函数,如果在这n秒内又被触发则重新计时。
场景:输入框键盘按下事件搜索。

节流:单位时间内只触发一次回调函数,如果在这个单位时间内有多次触发只有一次生效。
场景:下拉不触底加载、距离顶部一定距离出现返回顶部按钮。

前面我们使用 setTimeout 简单实现了防抖和节流功能,如果我们不考虑兼容性,追求精度比较高的页面效果,可以考虑试试 html5 提供的 requestAnimationFrame【 ie10- 不支持】
与 setTimeout 相比,requestAnimationFrame 不用我们书写时间间隔,它会根据当前电脑赫兹生成自己的绘制频率。requestAnimationFrame是浏览器用于定时循环操作的一个接口,类似于setTimeout,主要用途是按帧对网页进行重绘。设置这个API的目的是为了让各种网页动画效果(DOM动画、Canvas动画、SVG动画、WebGL动画)能够有一个统一的刷新机制,从而节省系统资源,提高系统性能,改善视觉效果。代码中使用这个API,就是告诉浏览器希望执行一个动画,让浏览器在下一个动画帧安排一次网页重绘。requestAnimationFrame的优势,在于充分利用显示器的刷新机制,比较节省系统资源。显示器有固定的刷新频率(60Hz或75Hz),也就是说,每秒最多只能重绘60次或75次,requestAnimationFrame的基本思想就是与这个刷新频率保持同步,利用这个刷新频率进行页面重绘。此外,使用这个API,一旦页面不处于浏览器的当前标签,就会自动停止刷新。这就节省了CPU、GPU和电力。

requestAnimationFrame 特点:
1)、绘制频率与电脑一致,不会出现丢频。
2)、当该元素被隐藏或不可见或页面未激活时会自动暂停,减少CPU和内存。
注意
1)、防抖和节流只是减少了事件回调函数的执行次数,并不会减少事件的触发频率。
2)、防抖和节流并没有从本质上解决性能问题,我们还应该注意优化我们事件回调函数的逻辑功能,避免在回调中执行比较复杂的DOM操作。
欢迎分享你们的理解与使用场景~