非常简单的视差代码存在性能问题

时间:2017-03-28 15:55:17

标签: javascript jquery performance parallax requestanimationframe

对于视差效果,我在原生Javascript中创建了一个简单的脚本,但似乎在我无法看到的地方失败了。这就是我已添加requestAnimationFrame - 功能的原因,但它似乎并没有真正帮助。

我的相关代码如下:

var $parallax, vh;
$(document).ready(function() {
    $parallax = $('.parallax');
    vh = $(window).height();

    $parallax.parallaxInit();
});

$(window).resize(function() {
    vh = $(window).height();

    $parallax.parallaxInit();
});


$.fn.parallaxInit = function() {
    var _ = this;
    _.find('.parallax-bg')
        .css('height', vh + (vh * .8) );

}



//call function on scroll
$(window).scroll(function() {
    window.requestAnimationFrame(parallax);
});

var parallaxElements = document.getElementsByClassName('parallax'),
    parallaxLength = parallaxElements.length;

var el, scrollTop, elOffset, i;

function parallax(){

    for( i = 0; i < parallaxLength; i++ ) {

        el = parallaxElements[i];
        elOffset = el.getBoundingClientRect().top;

        // only change if the element is in viewport - save resources
        if( elOffset < vh && elOffset + el.offsetHeight > 0) {

            el.getElementsByClassName('parallax-bg')[0].style.top = -(elOffset * .8) + 'px';

        }

    }

}

我觉得奇怪的是this script by Hendry Sadrak比我的脚本(在我的手机上)运行得更好,而据我所知,这并没有真正优化。

更新:我检查过某些Javascript怪物中getBoundingClientRect是否会变慢,但速度提高了约78%:https://jsperf.com/parallax-test

3 个答案:

答案 0 :(得分:3)

所以这是移动设备上JS动画的下行。不要依赖他们。

原因是移动设备配有电池,软件旨在最大限度地减少电池负载。制造商使用的技巧之一(Apple在其所有移动设备上执行此操作)在滚动时暂时暂停脚本执行。做像视差这样的事情尤其明显。您所看到的是代码执行 - 然后滚动,暂停执行,停止滚动,动画取消暂停并赶上。但这还不是全部。 iOS使用UI线程的实时优先级 - 这意味着滚动时滚动优先于所有其他操作 - 这将放大此延迟。

如果您需要在移动设备上进行流畅动画,请尽可能使用CSS动画。对Android的影响较小,因为优先级的处理方式不同,但有些滞后可能会很明显。

红色更多:https://plus.google.com/100838276097451809262/posts/VDkV9XaJRGS

答案 1 :(得分:1)

我修好了!我使用了transform: translate3d代替了GPU,而不是CPU。即使在移动设备上也能让它更流畅。

http://codepen.io/AartdenBraber/pen/WpaxZg?editors=0010

答案 2 :(得分:0)

创建新的jQuery对象非常昂贵,因此如果脚本多次使用它们,理想情况下您希望将它们存储在变量中。 (每次调用$(window)时都会创建一个新的jQuery对象。)

因此,在脚本顶部添加var $window = $(window);并使用该$(window)而不是再次调用{{1}}应该会有很多帮助。