节流和去抖的区别

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费积分!

前几天我将这两个概念搞混了,然后有人纠正了我。因此,我将其添加到我的博客文章想法列表中,现在我们就在这里。它们都是基于 DOM 事件限制 JavaScript 执行次数以提高性能的方法。但正如你所猜想的,它们是不同的。

节流强制限制函数在一段时间内被调用的最大次数。例如,“每 100 毫秒最多执行此函数一次”。

假设在正常情况下,您将在 10 秒内调用此函数 1000 次。如果您将其节流为每 100 毫秒调用一次,则该函数最多只会执行 100 次。

(10 秒 * 1000) = 10000 毫秒
10000 毫秒 / 100 毫秒节流 = 100 次最大调用

去抖强制确保在一段时间内函数不会再次被调用。例如,“仅当 100 毫秒内未调用此函数时才执行此函数”。

也许某个函数在 3 秒内以短促的爆发方式被调用了 1000 次,然后停止被调用。如果您将其去抖设置为 100 毫秒,则该函数只会在 3.1 秒时触发一次,即爆发结束后。在爆发期间每次调用该函数都会重置去抖计时器。

有什么意义?

这些概念的一个主要用例是某些 DOM 事件,例如滚动和调整大小。例如,如果您将滚动处理程序附加到某个元素,然后向下滚动该元素 5000 像素,您可能会看到触发了 100 多个事件。如果您的事件处理程序执行大量工作(例如繁重的计算和其他 DOM 操作),您可能会遇到性能问题(卡顿)。如果您可以在很大程度上减少处理程序的执行次数,而不会对体验造成太大影响,那么这样做可能值得。

快速示例

  • 等待用户停止调整窗口大小
  • 在用户停止输入之前不要触发 ajax 事件
  • 测量页面的滚动位置,并最多每 50 毫秒响应一次
  • 在应用程序中拖动元素时确保良好的性能

怎么做

这两个函数都内置于 UnderscoreLodash 中。即使您不完全使用这些库,您也可以随时从其中提取函数以供自己使用。

简单的节流滚动

$("body").on('scroll', _.throttle(function() {
  // Do expensive things
}, 100));

简单的去抖调整大小

$(window).on('resize', _.debounce(function() {
  // Do expensive things
}, 100));

从这里升级,您将使用 requestAnimationFrame,因此即使执行了函数,浏览器也会根据其自己的理想时机进行执行。这在 Paul Lewis 的本教程中有所介绍。

演示

简单的演示,以便您可以体验两者之间的差异

查看 Chris Coyier 在 CodePen 上的笔 节流、去抖和两者都不使用之间的区别@chriscoyier)。


更新: 更多演示!