jQuery animate() 和浏览器性能

Posted

技术标签:

【中文标题】jQuery animate() 和浏览器性能【英文标题】:jQuery animate() and browser performance 【发布时间】:2010-10-02 08:00:50 【问题描述】:

我有一些元素在页面上移动非常缓慢。本质上,我在 40 秒左右的时间内减少了两个图像的左边距。

从视觉上看,它运行良好。 但是,我的处理器在动画期间的使用率跃升至大约 50%。 这也不是特定于任何单一浏览器的 - 在 Safari3 和 Firefox3 上也是如此。如果我让两个浏览器都运行该页面,我的 CPU 会以大约 95% 的使用率尖叫。

我正在使用 jQuery 1.3。两个动画同时发生。页面上没有 Flash。如果我将代码注释掉(删除动画)并刷新页面,我的处理器会立即恢复正常使用。

我希望我不必求助于 Flash,但即使在 Hulu.com 上观看节目也不会像这样占用我的 CPU。

想法?

【问题讨论】:

【参考方案1】:

我知道这是一个老问题,Tim provided a great answer,但我只是想我应该为任何寻求此问题解决方案的人发布更新,因为现在有一种更简单的方法......

jQuery 1.4.3 开始,您可以通过 jQuery.fx.interval 属性直接设置 jQuery 的动画使用的间隔。所以你可以简单地做这样的事情:

jQuery.fx.interval = 50;

【讨论】:

这为所有动画设置了一个全局间隔。你碰巧知道如何为一个特定的动画设置间隔? @Marcel - 我不知道,我相信所有动画都共享相同的内部计时器,但我可能是错的...... 24fps,很多拍摄的速度,似乎代表了玩这个数字的一​​个很好的起点。所以,1000ms / 24fps = ~42 默认为13(毫秒)【参考方案2】:

我真的很喜欢 Tim 发布的答案,尽管我需要让这个修复程序在 Drupal 6 生产环境中工作。

我通过使用 jQuery 更新模块安装了 jQuery 1.3.2,因此我使用的与 Tim 的修复程序设计的 jQuery 1.4 之间存在一些差异。

按照 Tim 的指示,我完成了 90% 的工作,我只需要花 10 分钟的时间思考这个代码即可。

25 - 33 的计时器值似乎比 13 毫秒的中速动画效果好很多,例如褪色背景图像。

var timerId;

function now() 
    return (new Date).getTime();


jQuery.fx.prototype.custom = function( from, to, unit ) 
    this.startTime = now();
    this.start = from;
    this.end = to;
    this.unit = unit || this.unit || "px";
    this.now = this.start;
    this.pos = this.state = 0;

    var self = this;
    function t( gotoEnd ) 
        return self.step(gotoEnd);
    

    t.elem = this.elem;

        if ( t() && jQuery.timers.push(t) && !timerId ) 
    timerId = setInterval(function()
        var timers = jQuery.timers;

        for ( var i = 0; i < timers.length; i++ )
            if ( !timers[i]() )
                timers.splice(i--, 1);

        if ( !timers.length ) 
            clearInterval( timerId );
            timerId = undefined;
        
    , 25);

;

【讨论】:

【参考方案3】:

人们提到减慢 jQuery 的刷新率。您可以使用此文件 (jquery.animation-fix.js) 覆盖 jQuery 1.4 中的计时器功能:

function now() 
    return (new Date).getTime();

jQuery.fx.prototype.custom = function( from, to, unit ) 
    this.startTime = now();
    this.start = from;
    this.end = to;
    this.unit = unit || this.unit || "px";
    this.now = this.start;
    this.pos = this.state = 0;

    var self = this;
    function t( gotoEnd ) 
        return self.step(gotoEnd);
    

    t.elem = this.elem;

    if ( t() && jQuery.timers.push(t) && !jQuery.fx.prototype.timerId ) 
        //timerId = setInterval(jQuery.fx.tick, 13);
        jQuery.fx.prototype.timerId = setInterval(jQuery.fx.tick, 2050);
    

所以用这个修改行

jQuery.fx.prototype.timerId = setInterval(jQuery.fx.tick, 50);

将 50 更改为您想要的任何间隔。以毫秒 (ms) 为单位

如果您将此代码保存在不同的文件中,您可以像这样附加它:

<script src="/js/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="/js/jquery.animation-fix.js" type="text/javascript"></script>

【讨论】:

我只是在想,我想知道您可以将它捆绑到一个插件中,该插件可以在每个动画的基础上设置 setInterval。就像,您可以在api.jquery.com/animate 上添加一个参数,以更改该项目的间隔。嗯。 蒂姆,这正是我一直在寻找的!我喜欢你的工作:) 使用此解决方案的任何人请注意:此功能现在是 built in to jQuery, as of 1.4.3。 (虽然 +1 是 1.4.3 之前的一个很好的解决方案)。【参考方案4】:

jQuery animate 使用 javascript 函数 'setInterval' 每隔几毫秒更新一次对象。不幸的是,jQuery 中的间隔默认为“13 毫秒”。那是每秒 76 次更新。对于这样的慢速和中等动画来说,这是非常重要的。

13ms 被硬编码到 jQuery 中。所以你只能在jQuery.js中直接改变这个值。如果你只有缓慢的 clowds,你可以达到 100 毫秒。如果你也有一些更快的动画,你应该把它设置为 50。

您可以更改 setInterval() 的参数;在自定义函数中。 'jQuery.fx.prototype ... custom: function() ... ... '

【讨论】:

这将是一个杀手级的 jQuery 插件。向 animate() 添加间隔参数的东西。【参考方案5】:

我刚刚观察了 Scriptaculous 下动画的性能,发现了类似的 CPU 峰值:IE 大约为 50%,Firefox 的性能稍好(16-30%)——两者都在 DuoCore PC 上。由于 JQuery 和 Scriptaculous 都是通过更改底层 CSS 来工作的,所以我认为可以肯定地说任何 Javascript 实现在计算上都会很昂贵。

您很可能会被 Flash 卡住。

【讨论】:

【参考方案6】:

动画涉及循环操作,无论如何,这些操作都会真正消耗 CPU。

我不知道用 jQuery 做起来有多容易,但需要做的是动画需要消耗更少的周期。要么你让 ani 更加锯齿(显示不那么流畅),循环需要优化,或者减少 ani 的工作。

40 秒?动画是不是有点长?我认为他们应该比这更直接。

【讨论】:

动画是页面顶部云彩的微妙移动。它们从一个随机位置开始,然后慢慢向左移动。【参考方案7】:

我认为 jQuery animate() 的工作方式是它使用一个计时器,该计时器定期触发并调用一个更新 DOM 以反映动画状态的函数。通常动画相对较短,它们可能覆盖相当多的屏幕空间,所以我怀疑(没有确认)计时器到期并以相当高的速率重置以生成流畅的动画。由于您的动画需要很长时间,您可以修改 animate 函数,以便可以通过选项设置动画进行的速率。在您的情况下,您只需要每 250 毫秒左右更新一次,因为您大约每秒覆盖大约 3-4 个像素。

【讨论】:

由于动画已经很慢,我想知道这是否会使动画以锯齿状的方式向前移动。试图避免页面看起来像旧的 Atari 游戏。哈哈。我不知道,你认为 Flash 在这方面会更好吗? 没有。您必须使整个页面闪烁。 IIRC,你不能把它作为背景元素 此位将位于站点的标题区域中。所以我认为在热门内容后面放一个 Flash 电影实际上可能是一种选择。不过,我不知道实际创建 Flash 电影的第一件事。我经常和他们一起工作,但我不创作他们。 :-/ 接受这个是因为对问题性质的详细描述和建议的解决方法。不过还是谢谢大家!第一个 Stackedoverflow 问题取得了巨大的成功。我也会回来帮助其他人的。 如果您不需要它作为背景,那么 Flash 是一个选项。

以上是关于jQuery animate() 和浏览器性能的主要内容,如果未能解决你的问题,请参考以下文章

jquery animate bug,仅在谷歌浏览器中

Jquery animate() 和谷歌浏览器问题

如何使用 jquery animate 滚动到元素跨浏览器

jQuery .animate() 只在 Chrome 中动画,在其他浏览器中瞬时变化

JQuery.animate() 在某些浏览器上以不同的速度移动 div

jQuery animate 是不是在现代浏览器上使用 css3 过渡?