如何减少 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 尝试同时设置动画之间没有冲突。