提高背景视差滚动性能

4

你好,StackOverflow社区,

我想实现的是一个可以用鼠标移动的标题。当你点击标题并拖动鼠标时,标题内的元素将以不同的速度移动。

我已经实现了视差效果,但性能并不是很好。在拖动背景时有点卡顿。

我的问题是:代码中可以做哪些改变来提高性能?

这是处理视差效果的代码部分。每次鼠标移动时,都会执行一个each循环,我认为这就是性能卡顿的原因:

var dragging = false;
var clickMouseX;

//Our object for the layers
//each layer has a different scrolling speed
var movingObjects = {
    '#header-l1' : {'speed': 1},
    '#header-l2' : {'speed': 1.4},
    '#header-l3' : {'speed': 1.85},
    '#header-l4' : {'speed': 2.2},
};

$('#header-wrapper').mousedown(function(e){
    dragging = true;

    //Get initial mouse position when clicked
    clickMouseX = e.pageX;

        $(this).mousemove(function(mme){
            //execute only if mousedown
            if(dragging){
                //iterate through all layers which have to be parallaxed
                $.each(movingObjects, function(el, opt){
                    var element = $(el);
                    //get difference of initial mouse position and current mouse position
                    var diff = clickMouseX - mme.pageX;
                    //scroll-position left speed 1
                    if(diff < 0) diff = -1;
                    //scroll position right speed 1
                    if(diff >= 0) diff = 1;
                    //get current position of layer
                    currLeft = parseInt(element.css('left'));
                    //get current layer width
                    elWidth = element.width();

                    //if right border is reached don't scroll further
                    if(currLeft < -(elWidth - 810)){
                        element.css('left', -(elWidth - 810));
                    }           
                    //so do with left border
                    if(currLeft > 0){
                        element.css('left', 0);
                    }
                    //parallax it! Subtract the scroll position speed multiplied by the speed of the desired
                    //layer from the current left property
                    element.css('left', parseInt(element.css('left')) - diff*opt.speed);    
                });
            }
        });


    /* Cursor */
    $(this).css('cursor', 'pointer');
    return false;
});

我放了一个演示: http://jsfiddle.net/yWGDz/ 提前感谢, Thomas
附言:也许有人能找出为什么第二层和第三层具有不同速度,但滚动速度相同的原因。
3个回答

3
我稍微做了一些工作,得到了这个结果:http://jsfiddle.net/amqER/2/。这比原来的代码快得多(特别是在火狐浏览器中表现更好,在谷歌浏览器中仍然很慢)。我还改变了你代码中的一些逻辑,使它更加合理。我所做的事情包括:

压缩PNG图片

你的2个png文件超过了2兆,所以我把它们放入了一个png压缩器(tinypng)中,这样可以大大减小它们的大小。这有助于加载时间和整体响应速度。

尽可能多地重用值

在你的原始代码中,你几次写入并随后读取css的left属性。这样做会使它变得更慢。相反,我保留了一个左属性,并且只在绝对需要时才会使用$.css。同样,在每次更新时读取每个元素的宽度也是如此。
此外,如我所说,我修改了你的逻辑(我认为),以符合你想要实现的目标。它每次更新都会计算一个新的差异,并试图根据它移动。此外,一旦其中一个图像掉落,它就不会再尝试移动(如果你将所有内容都移到右侧,你的代码会这样做,看起来非常奇怪)。你还可以查看这个:http://jsfiddle.net/amqER/5/,也许更像你想要的控制方案。

哇!我绝对没有想到这个。它绝对很棒,我认为你的解决方案修复了我所有的逻辑缺陷。现在它运行得非常好!非常感谢你。我欠你一个人情。 - thpl

1
虽然Xymostech的答案确实对原帖中的代码进行了大幅改进,但在Chrome浏览器中,我的性能几乎没有得到改善。
检查页面FPS时,这里发布的解决方案在Retina MacBook Pro上以15FPS运行。
我对代码进行了非常简单的更改,将其改为使用translate3d属性而不是left。现在,它以55-60 FPS运行。我认为这是巨大的性能提升。
如果在Chrome中打开“显示绘画矩形”,则会看到之前发布的解决方案在视差移动时不断绘制DOM更改。使用translate3d解决方案,在整个视差移动过程中根本不需要绘制。

http://jsfiddle.net/LG47e/


1

以下是一些快速的性能优化技巧。

尽量不要使用 $(this).mousemove,而是将 $(this) 保存到一个变量中并使用它。

var th = $(this);
th.mousemove...

尽量避免使用$.each。这可能是减慢代码速度的部分。 你可以用for循环替换它,但在这种情况下,我建议逐个发送每个元素。

var parallax = function(img){

};

parallax(img1);
parallax(img2);

立即提高你的jQuery性能


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接