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() 只在 Chrome 中动画,在其他浏览器中瞬时变化