如何减少 javascript 滚动/CSS 转换中的 FPS 下降
How to reduce FPS drops in javascript scroll / CSS transitions
我已经陷入了性能分析和优化的困境,我无法减少应该是相当轻量级变换的帧速率下降,尽管我怀疑它在滚动条上,尽管节流可能是罪魁祸首?
我想实现的就是这个简单的slow/smooth滚动效果,如下所示:JSFiddle
未节流的 jQuery 版本..
JS
w = $(window);
b = $('body');
c = $('#container');
$(document).ready(function() {
w.scroll(function() {
c.css('transform','translateY(' + -w.scrollTop() + 'px)');
});
});
CSS
html, body { margin: 0; }
body {
height: 500vh;
}
#container {
display: block;
position: fixed;
height: 500vh;
width: 100vw;
background: #814e4e;
padding: 20%;
font-size: 30px;
line-height: 45px;
color: #fff;
text-align: center;
transform: translate3d(0,0,0);
will-change: transform;
transition: transform 1.5s ease-out;
}
HTML
<body>
<div id="container">
<p>Lorem ipsum...</p>
</div>
</body>
我已经从 underscore.js 中删除了节流功能,并在 GSAP 中重写了整个功能,在所有情况下,在不同程度上,平均 FPS 下降了 10-20。令人惊讶的是,在滚动功能上,节流 jquery 版本并没有比正常 jquery 版本有很大改进,而 GSAP 版本使用了他们新的滚动触发器插件,比上面任何一个都不流畅。任何关于这个或我可以尝试的推荐方法的建议都将不胜感激!
.scrollTop
导致回流并且性能不佳。这是你的主要问题。
其次,您使用的是 .scroll
函数,该函数会创建一个新动画来影响每个刻度的滚动位置,因此这也不是高效的。
第三,您正在应用一个 CSS 过渡,它试图在每个刻度中为 属性 设置动画,因此这也不是高效的。
如果您解决了以上所有问题,您仍然应该限制滚动事件。
更小的是,jQuery 比 vanilla JS 慢。
由于您使用 GSAP 标记了它并尝试使用 ScrollTrigger,here's how you can do it with ScrollTrigger。这是我之前做的一个demo,效果是一样的
关于为什么它更高效的一些关键:
- ScrollTrigger 计算动画应该何时开始和结束,并且仅在页面的该部分期间进行动画处理。
- 滚动事件去抖动。更新与屏幕刷新同步。
- 所有滚动计算都在同一个更新方法中完成。
- 页面的自然滚动位置不受影响。
- GSAP 自动使用 3D 转换来利用 GPU 上的渲染。
- 之前创建的任何动画都会被以后的动画终止。
- JS 设置的定位与CSS 尝试同时设置动画之间没有冲突。
我已经陷入了性能分析和优化的困境,我无法减少应该是相当轻量级变换的帧速率下降,尽管我怀疑它在滚动条上,尽管节流可能是罪魁祸首?
我想实现的就是这个简单的slow/smooth滚动效果,如下所示:JSFiddle
未节流的 jQuery 版本..
JS
w = $(window);
b = $('body');
c = $('#container');
$(document).ready(function() {
w.scroll(function() {
c.css('transform','translateY(' + -w.scrollTop() + 'px)');
});
});
CSS
html, body { margin: 0; }
body {
height: 500vh;
}
#container {
display: block;
position: fixed;
height: 500vh;
width: 100vw;
background: #814e4e;
padding: 20%;
font-size: 30px;
line-height: 45px;
color: #fff;
text-align: center;
transform: translate3d(0,0,0);
will-change: transform;
transition: transform 1.5s ease-out;
}
HTML
<body>
<div id="container">
<p>Lorem ipsum...</p>
</div>
</body>
我已经从 underscore.js 中删除了节流功能,并在 GSAP 中重写了整个功能,在所有情况下,在不同程度上,平均 FPS 下降了 10-20。令人惊讶的是,在滚动功能上,节流 jquery 版本并没有比正常 jquery 版本有很大改进,而 GSAP 版本使用了他们新的滚动触发器插件,比上面任何一个都不流畅。任何关于这个或我可以尝试的推荐方法的建议都将不胜感激!
.scrollTop
导致回流并且性能不佳。这是你的主要问题。
其次,您使用的是 .scroll
函数,该函数会创建一个新动画来影响每个刻度的滚动位置,因此这也不是高效的。
第三,您正在应用一个 CSS 过渡,它试图在每个刻度中为 属性 设置动画,因此这也不是高效的。
如果您解决了以上所有问题,您仍然应该限制滚动事件。
更小的是,jQuery 比 vanilla JS 慢。
由于您使用 GSAP 标记了它并尝试使用 ScrollTrigger,here's how you can do it with ScrollTrigger。这是我之前做的一个demo,效果是一样的
关于为什么它更高效的一些关键:
- ScrollTrigger 计算动画应该何时开始和结束,并且仅在页面的该部分期间进行动画处理。
- 滚动事件去抖动。更新与屏幕刷新同步。
- 所有滚动计算都在同一个更新方法中完成。
- 页面的自然滚动位置不受影响。
- GSAP 自动使用 3D 转换来利用 GPU 上的渲染。
- 之前创建的任何动画都会被以后的动画终止。
- JS 设置的定位与CSS 尝试同时设置动画之间没有冲突。