9

我正在使用 Intersection Observer API,我想知道:

如何对 Intersection Observer API 进行去抖动或限制?

如果我想提高性能,你推荐使用 debounce 或 throttle 功能吗?

4

2 回答 2

4

一般的观察者(不仅是交叉观察者,还有变异观察者,......)都由浏览器处理。这意味着浏览器决定何时执行观察者。

这就是为什么您只定义阈值并且根据负载,它们或多或少是准确的。例如,当您在 Intersection Observer 上定义 20% 的阈值时,它可能会在 20.6% 处执行。那是因为浏览器会自动去抖动(这里的延迟可能是更好的词)函数,并且只有在它有足够的资源来执行它时才执行它。

这也适用于所有其他观察者。

于 2019-12-17T07:16:59.120 回答
3

我想首先说Intersection Observer API 已经非常高效,并提供了几种配置来根据需要或多或少地发生回调,从而避免了去抖动或限制其调用的必要性。如果您想了解更多信息,请快速阅读我整理的关于 Intersection Observer API 的这篇文章。

话虽如此,我们需要了解threshold配置的属性是如何工作的。threshold来自0和之间的任何数字1,它接受一个数字或一个数字数组。所以以下所有内容options都是有效的:

const sneakPeekOptions = {threshold: 0};
const fullOptions = {threshold: 1};
const progressiveOptions = {threshold: [0, .25, .5, .75, 1]};

为了更好地理解threshold,可以将这些值乘以,100结果将告诉我们将触发回调的目标的可见性百分比。这意味着:

// When 0% is visible
const sneakPeekOptions = {threshold: 0};

// When 100% is visible
const fullOptions = {threshold: 1};

// When 0%, 25%, 50%, 75% and 100% is visible
const progressiveOptions = {threshold: [0, .25, .5, .75, 1]};

所以对于sneakPeekOptionsfullOptions很明显,这只会在用户滚动时发生一次,所以让我们专注于那个progressiveOptions

现在我们必须添加另一个变量,它是被观察元素的高度(或宽度?它取决于滚动方向,所以现在让我们关注高度和垂直滚动)。让我们提出两个节点元素:

<head>
  .
  .
  .
  <style>
    .small-target { height: 4px }
    .large-target { height: 100px }
  </style>
</head>
<body>
  . // More elements creating scroll
  .
  .
  <div class="small-target></div>
  <div class="large-target></div>
  .
  .
  . // More elements creating scroll
</body>

这两个元素.small-target分别.large-target有 4px 和 100px 的高度。所以现在让我们执行以下 JS 行:

const smallTarget = document.querySelector('.small-target');
const largeTarget = document.querySelector('.large-target');

const progressiveOptions = {threshold: [0, .25, .5, .75, 1]};
const callback = (e, o) => {}; // To be called on each threshold.

const observer = new IntersectionObserver(callback, progressiveOptions);

observer.observe(smallTarget);
observer.observe(largeTarget);

如上所示,我们正在配置一个带有阈值数组的观察者来观察具有不同高度的两个元素。现在,考虑到用户以每秒 1px 的速度滚动(让我们想象这是可能的),调用callback函数的频率将根据元素的高度发生巨大变化:

呼吁smallTarget

在这种情况下,该callback函数每秒将被调用 1 次,这意味着在 4 秒后它将总共有 5 次调用:

  1. 0px 的一次通话 – 0 秒 – 开始
  2. 1px 的一次通话 – 1 秒 – 滚动
  3. 2px 的一次通话 – 2 秒 – 滚动
  4. 3px 的一次通话 – 3 秒 – 滚动
  5. 4px 的一次通话 – 4 秒 – 结束

呼吁largeTarget

现在,在这种情况下,该callback函数将每 25 秒被调用 1 次,这意味着在 100 秒后它将总共有 5 次调用:

  1. 0px 的一次通话 – 0 秒 – 开始
  2. 25 像素的一次通话 – 25 秒 – 滚动
  3. 50 像素的一次通话 – 50 秒 – 滚动
  4. 75 像素的一次通话 – 75 秒 – 滚动
  5. 100 像素的一次通话 – 100 秒 – 结束

我认为这是描绘同一个观察者如何根据被观察组件的高度或多或少地执行调用的好方法。

建议

如果您发现 IntersectionObserver 被频繁调用,请尝试使用阈值配置和观察到的元素的高度,我可以向您保证,有一种方法可以通过更改阈值或使用来降低此调用的频率一个单独的 Intersection Observer 实例。

尽管我认为这应该涵盖您可能面临的所有情况,但如果您在调整阈值后仍需要去抖动和/或节流,我很想了解更多关于这种情况的信息,并在可能的情况下提供更好的答案。

于 2021-02-07T09:37:45.957 回答