草庐IT

Javascript OnScroll 性能比较

coder 2024-05-10 原文

更新:类似的问题有一个很好的答案,展示了如何以有用的方式将 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 函数被调用的频率,但是比较不同代码片段的性能是一个糟糕的测试。

这是执行的性能记录:

函数 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 OnScroll 性能比较的更多相关文章

  1. ruby - Ruby 的 Hash 在比较键时使用哪种相等性测试? - 2

    我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。

  2. ruby - 是否有用于复杂比较的漂亮语法? - 2

    方法应返回-1,0或1分别表示“小于”、“等于”和“大于”。对于某些类型的可排序对象,通常将排序顺序基于多个属性。以下是可行的,但我认为它看起来很笨拙:classLeagueStatsattr_accessor:points,:goal_diffdefinitializepts,gd@points=pts@goal_diff=gdenddefothercompare_pts=pointsother.pointsreturncompare_ptsunlesscompare_pts==0goal_diffother.goal_diffendend尝试一下:[LeagueStats.new(

  3. Ruby 的数字方法性能 - 2

    我正在使用Ruby解决一些ProjectEuler问题,特别是这里我要讨论的问题25(Fibonacci数列中包含1000位数字的第一项的索引是多少?)。起初,我使用的是Ruby2.2.3,我将问题编码为:number=3a=1b=2whileb.to_s.length但后来我发现2.4.2版本有一个名为digits的方法,这正是我需要的。我转换为代码:whileb.digits.length当我比较这两种方法时,digits慢得多。时间./025/problem025.rb0.13s用户0.02s系统80%cpu0.190总计./025/problem025.rb2.19s用户0.0

  4. ruby - Ruby 性能中的计时器 - 2

    我正在寻找一个用ruby​​演示计时器的在线示例,并发现了下面的代码。它按预期工作,但这个简单的程序使用30Mo内存(如Windows任务管理器中所示)和太多CPU有意义吗?非常感谢deftime_blockstart_time=Time.nowThread.new{yield}Time.now-start_timeenddefrepeat_every(seconds)whiletruedotime_spent=time_block{yield}#Tohandle-vesleepinteravalsleep(seconds-time_spent)iftime_spent

  5. ruby-on-rails - 如果条件与 &&,是否有任何性能提升 - 2

    如果用户是所有者,我有一个条件来检查说删除和文章。delete_articleifuser.owner?另一种方式是user.owner?&&delete_article选择它有什么好处还是它只是一种写作风格 最佳答案 性能不太可能成为该声明的问题。第一个要好得多-它更容易阅读。您future的自己和其他将开始编写代码的人会为此感谢您。 关于ruby-on-rails-如果条件与&&,是否有任何性能提升,我们在StackOverflow上找到一个类似的问题:

  6. ruby - 尝试比较两个文本文件,并根据信息创建第三个 - 2

    我有两个文本文件,master.txt和926.txt。如果926.txt中有一行不在master.txt中,我想写入一个新文件notinbook.txt。我写了我能想到的最好的东西,但考虑到我是一个糟糕的/新手程序员,它失败了。这是我的东西g=File.new("notinbook.txt","w")File.open("926.txt","r")do|f|while(line=f.gets)x=line.chompifFile.open("master.txt","w")do|h|endwhile(line=h.gets)ifline.chomp!=xputslineendende

  7. ruby-on-rails - 我如何比较 'Bcrypt' Gem解密的密码和加密的密码 - 2

    我正在尝试对某些帖子的评论使用简单的身份验证。用户使用即时ID和密码输入评论我使用“bcrypt”gem将密码存储在数据库中。在comments_controller.rb中像这样@comment=Comment.new(comment_params)bcrypted_pwd=BCrypt::Password.create(@comment.user_pwd)@comment.user_pwd=bcrypted_pwd当用户想要删除他们的评论时,我使用data-confirm-modalgem来确认数据在这部分,我必须解密用户输入的密码以与数据库中的加密密码进行比较我怎样才能解密密码,

  8. ruby - Date 与 nil 的比较失败 - ruby - 2

    我正在运行这样的代码:ifvalid_from>Date.today当我运行它时,我得到一个错误提示comparisonofDatewithnilfailed我假设它正在发生,因为在某些情况下valid_from是nil。有没有办法避免出现此错误? 最佳答案 你可以这样做:ifvalid_fromandvalid_from>Date.today...end这将在第一个子句上短路,因为valid_from为nil,因此为false。 关于ruby-Date与nil的比较失败-ruby,我们

  9. ruby - 如何找到我的 Ruby 应用程序中的性能瓶颈? - 2

    我编写了一个Ruby应用程序,它可以解析来自不同格式html、xml和csv文件的源中的大量数据。我如何找出代码的哪些区域花费的时间最长?有没有关于如何提高Ruby应用程序性能的好资源?或者您是否有任何始终遵循的性能编码标准?例如,你总是用加入你的字符串吗?output=String.newoutput或者你会使用output="#{part_one}#{part_two}\n" 最佳答案 好吧,有一些众所周知的做法,例如字符串连接比“#{value}”慢得多,但是为了找出您的脚本在哪里消耗了大部分时间或比所需时间更多,您需要进行分

  10. STM32的HAL和LL库区别和性能对比 - 2

    LL库和HAL库简介LL:Low-Layer,底层库HAL:HardwareAbstractionLayer,硬件抽象层库LL库和hal库对比,很精简,这实际上是一个精简的库。LL库的配置选择如下:在STM32CUBEMX中,点击菜单的“ProjectManager”–>“AdvancedSettings”,在下面的界面中选择“AdvancedSettings”,然后在每个模块后面选择使用的库总结:1、如果使用的MCU是小容量的,那么STM32CubeLL将是最佳选择;2、如果结合可移植性和优化,使用STM32CubeHAL并使用特定的优化实现替换一些调用,可保持最大的可移植性。另外HAL和L

随机推荐