Javascript OnScroll 性能比较

标签 javascript jquery scroll onscroll

更新:类似的问题有一个很好的答案,展示了如何以有用的方式将 requestAnimationFrame 与滚动一起使用: scroll events: requestAnimationFrame VS requestIdleCallback VS passive event listeners


假设我想在我的网站上添加一些由滚动触发的昂贵操作。例如,我在我的 jsfiddle 中使用了视差效果。

现在我一直在读它一定不能直接绑定(bind)到事件上,有时后面跟着一些旨在更好的片段。举几个例子:

  1. Attaching JavaScript Handlers to Scroll Events = BAD!
  2. How to develop high performance onScroll event?
  3. How to make faster scroll effects?
  4. 60FPS onscroll event listener

他们说的基本上是不要这样做:

  // Bad guy 1
  $(window).scroll( function() {
    animate(ex1);
  });

或者这个

  // Bad guy 2
  window.addEventListener('scroll', onScroll, false);
  function onScroll() {
    animate(ex2);
  }

但是使用超时、间隔、requestAnimationFrame 等等,例如:

  // Good guy
  $(window).scroll( function() {
   scrolling1 = true;
  });

  setInterval( function() {
    if (scrolling1) {
      scrolling1 = false;
      animate(ex3);
    }
  }, 50 );

因此,我将在上面的链接中找到的选项添加到一个 jsfiddle,该 jsfiddle 试图通过为每种方法添加一个计数器来比较它们,如下所示:

  // Test
  $(window).scroll( function() {
    counter = counter + 1;
    // output result of counter
    animate(ex1);
  });

最好检查完整jsfiddle

结果:一切顺利的原因在于计算次数大致相同。如果我能忍受波涛汹涌的影响,也许我可以保护一些资源。与我阅读的所有内容相反,这对我来说似乎合乎逻辑!

第一个问题: 我错过了什么或者这是一个有效的测试吗?如果它无效,我怎么能正确测试? 编辑:澄清一下,我想测试以上任何方法是否完全节省性能。

第二个问题: 如果有效,为什么每个人都对 onscroll 感到紧张?如果流体动画需要在整个站点上进行 5000 次计算,那么无论如何都无法更改它吗?

(好吧,有时我会使用检查来确定一个对象是否在视口(viewport)中,但老实说,我什至不知道这些检查是否没有被阻止的代码本身那么昂贵,尤其是当它们涉及五个不同的偏移量、windowHeight、scrolltTop、getBoundingClientRect 和 outerHeight 等变量...)

最佳答案

所以,@SirPeople 已经正确回答了你的第一个问题,它确实是一个很好的测试来查看 animate 函数被调用的频率,但是比较不同代码片段的性能是一个糟糕的测试。

这是执行的性能记录:

performance test

函数 animate 一点也不昂贵。我拍摄了一个性能记录(下一张图片),它显示在我查看的一次迭代中它花费了 0.64 毫秒到 1.29 毫秒(第 1-5 点)。而且一旦功能完成,重绘根本不需要时间(第 6 点),这可能是因为页面几乎没有内容。当我们查看时间时,我们可以看到所有五个动画函数和重绘都在不到 10 毫秒的时间内完成,这在正常情况下意味着我们可以获得流畅的 60fps 动画(第 7 点)。

此外,如果我们想要比较 onscroll 事件监听器,我们需要单独测试每个监听器并比较结果。如果其中一个监听器真的被阻止,它将对整个页面产生影响,并且如果不进行性能调试,您将不知道它是哪个。

我制作了两个 jsfiddle window.scrollRAF .而且,令我惊讶的是,似乎没有任何区别。

人们为什么关心这个?

正如您在上面链接的 jsfiddles 中看到的那样,如果事件处理程序变得太大,整个页面将会滞后。

现在怎么办?

我自己不是性能大师,但是:

关于Javascript OnScroll 性能比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51329892/

相关文章:

javascript - document.getElementById 在将 svg 移动到对象标记中时导致 null

javascript - 当类型值相等时如何禁用字段

javascript - 随机变量网格

c# - EmailAddress DataAnnotation 在 View 上标记为有效但 ModelState.IsValid = false?

android - 创建一个不带 ScrollView 的可滚动 LinearLayout

javascript - Ajax 加载后重新初始化内容脚本?

javascript - 使用 Jquery 的 AJAX 无法跨 JSP 页面工作

javascript - 如何在 Meteor JS 中水平对齐 div/配置文件卡?

css - Div 中复杂滚动行为的宽度问题

jQuery - 使用浏览器滚动条控制 div 滚动