更新:类似的问题有一个很好的答案,展示了如何以有用的方式将 requestAnimationFrame 与滚动一起使用: scroll events: requestAnimationFrame VS requestIdleCallback VS passive event listeners
假设我想在我的网站上添加一些由滚动触发的昂贵操作。例如,我在我的 jsfiddle 中使用了视差效果。
现在我一直在读它一定不能直接绑定(bind)到事件上,有时后面跟着一些旨在更好的片段。举几个例子:
- Attaching JavaScript Handlers to Scroll Events = BAD!
- How to develop high performance onScroll event?
- How to make faster scroll effects?
- 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.scroll和 RAF .而且,令我惊讶的是,似乎没有任何区别。
人们为什么关心这个?
正如您在上面链接的 jsfiddles 中看到的那样,如果事件处理程序变得太大,整个页面将会滞后。
现在怎么办?
我自己不是性能大师,但是:
- 也许其他解决方案之一是正确的
- 我们可以将您的事件监听器标记为被动,尽管在我的 test 中它根本没有真正改善 https://developers.google.com/web/updates/2016/06/passive-event-listeners
- 我们可以通过消除视差效应来优化事件监听器
- 还有一个叫做 Intersection Observer 的新东西,它应该快得多,我没有测试它 https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API
关于Javascript OnScroll 性能比较,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51329892/