jQuery animate() 和浏览器性能
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/459224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery animate() and browser performance
提问by Jeremy Ricketts
I've got some elements that I'm moving across the page very slowly. Essentially, I'm decreasing the left margin of two images over a span of 40 seconds or so.
我有一些元素在页面上移动得非常缓慢。本质上,我是在 40 秒左右的时间内减少两个图像的左边距。
Visually, it's working beautifully. However, my processor jumps to about 50% usage during the animations.This isn't specific to any single browser either- it's the same way on Safari3 and Firefox3. If I have both browsers running the page, my CPU is screaming at about 95% usage.
在视觉上,它工作得很好。但是,我的处理器在动画期间跳到大约 50% 的使用率。这也不是特定于任何单个浏览器 - 在 Safari3 和 Firefox3 上也是如此。如果我有两个浏览器都在运行该页面,我的 CPU 会以大约 95% 的使用率尖叫。
I'm using jQuery 1.3. Both animations are happening concurrently. There's no Flash on the page. If I comment the code out (remove the animation) and refresh the page, my processor immediately returns to normal usage.
我正在使用 jQuery 1.3。两个动画同时发生。页面上没有 Flash。如果我注释掉代码(删除动画)并刷新页面,我的处理器会立即恢复正常使用。
I'm hoping I don't have to resort to Flash, but even watching shows on Hulu.com doesn't spike my CPU like this.
我希望我不必求助于 Flash,但即使在 Hulu.com 上观看节目也不会像这样消耗我的 CPU。
Thoughts?
想法?
采纳答案by tvanfosson
I think the way jQuery animate() works is that it uses a timer that periodically fires and invokes a function that updates the DOM to reflect the state of the animation. Typically animations are relatively short and they may cover a fair amount of screen real estate, so I suspect (without confirming) that the timer expires, and is reset, at a fairly high rate to generate a smooth animation. Since your animation takes a long time, you might be able to modify the animate function so that the rate at which the animation proceeds can be set via an option. In your case you'd only need to update every 250ms or so since you're covering about 3-4 pixels per second, roughly.
我认为 jQuery animate() 的工作方式是它使用一个计时器,该计时器定期触发并调用更新 DOM 以反映动画状态的函数。通常动画相对较短,它们可能会覆盖相当多的屏幕空间,所以我怀疑(没有确认)计时器到期并以相当高的速率重置以生成平滑的动画。由于您的动画需要很长时间,您可以修改 animate 函数,以便可以通过选项设置动画进行的速率。在您的情况下,您只需要每 250 毫秒左右更新一次,因为您大约每秒覆盖 3-4 个像素。
回答by Alconja
I know this is an oldish question and Tim provided a great answer, but I just thought I should post an update for anyone looking for a solution to this problem, since there's now a simpler way...
我知道这是一个陈旧的问题,蒂姆提供了一个很好的答案,但我只是想我应该为任何寻求解决此问题的人发布更新,因为现在有一种更简单的方法......
As of jQuery 1.4.3you can set the interval jQuery's animate uses directly via the jQuery.fx.intervalproperty. So you can simply do something like:
从jQuery 1.4.3 开始,您可以直接通过jQuery.fx.interval属性设置 jQuery 动画使用的间隔。因此,您可以简单地执行以下操作:
jQuery.fx.interval = 50;
回答by Tim
People have mentioned slowing down jQuery's refresh rate. You can override the timer function in jQuery 1.4 with this file (jquery.animation-fix.js):
人们提到减慢 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);
}
}
So modify the line with this in it
所以用这个修改行
jQuery.fx.prototype.timerId = setInterval(jQuery.fx.tick, 50);
Change the 50 to whatever interval you want. That is in Miliseconds (ms)
将 50 更改为您想要的任何间隔。即以毫秒 (ms) 为单位
If you save this code in a different file, you can attach it like this:
如果将此代码保存在不同的文件中,则可以像这样附加它:
<script src="/js/jquery-1.4.2.min.js" type="text/javascript"></script>
<script src="/js/jquery.animation-fix.js" type="text/javascript"></script>
回答by Alexander von Weiss
jQuery animate uses the javascript function 'setInterval' to update the obects every few milliseconds. Unfortunately the interval in jQuery is per default '13ms'. Thats 76 updates every second. Way to much for such slow and medium animations.
jQuery animate 使用 javascript 函数“setInterval”每隔几毫秒更新一次对象。不幸的是,jQuery 中的间隔默认为“13ms”。那是每秒 76 次更新。这种慢速和中速动画的方式太多了。
The 13ms are hardcoded into jQuery. So you can directly change this value in the jQuery.js, only. If you only have the slow clowds you can go up to 100ms. If you have some faster animations, too, you should set it to 50.
13ms 被硬编码到 jQuery 中。所以你只能在 jQuery.js 中直接改变这个值。如果你只有缓慢的人群,你可以达到 100 毫秒。如果您也有一些更快的动画,则应将其设置为 50。
You can change the parameter for setInterval(); in the function custom. 'jQuery.fx.prototype { ... custom: function() { ... } ... }'
您可以更改 setInterval() 的参数;在函数自定义中。'jQuery.fx.prototype { ... 自定义:function() { ... } ... }'
回答by StingyHyman
Animations involve looping operations, and those will really crunch the CPU no matter what.
动画涉及循环操作,无论如何这些操作都将真正消耗 CPU。
I dont know how easy it is to do with jQuery, but what needs to happen is the animation needs to consume less cycles. Either you make the ani a little more jagged (the display isnt as smooth), the looping needs to be optimized, or reduce the work of the ani.
我不知道用 jQuery 做起来有多容易,但需要发生的是动画需要消耗更少的周期。要么你让ani多一点锯齿(显示不是那么平滑),循环需要优化,或者减少ani的工作。
40 seconds? isnt that a bit long for an animation? I thought they are sposed to be a little more immediate than that.
40秒?动画是不是有点长?我认为他们应该比那更直接一点。
回答by rtperson
I just watched the performance of animation under Scriptaculous, and found similar CPU spikes: roughly 50% for IE, slightly better performance (16-30%) for Firefox -- both on a DuoCore PC. Since both JQuery and Scriptaculous work by changing the underlying CSS, I think it's safe to say that any Javascript implementation is going to be computationally expensive.
我刚刚在 Scriptaculous 下观看动画的性能,发现类似的 CPU 峰值:IE 大约为 50%,Firefox 的性能稍好(16-30%)——两者都在 DuoCore PC 上。由于 JQuery 和 Scriptaculous 都是通过更改底层 CSS 来工作的,我认为可以肯定地说任何 Javascript 实现都会在计算上很昂贵。
You may well be stuck going with Flash.
您很可能会坚持使用 Flash。
回答by David Meister
I really like the answer posted by Tim, although I needed to get this fix working in a Drupal 6 production environment.
我真的很喜欢 Tim 发布的答案,尽管我需要让这个修复程序在 Drupal 6 生产环境中工作。
I have jQuery 1.3.2 installed, through the use of jQuery update module, so there are a few differences between what I'm using and jQuery 1.4 that Tim's fix is designed for.
我通过使用 jQuery 更新模块安装了 jQuery 1.3.2,因此我使用的内容与 Tim 的修复程序所针对的 jQuery 1.4 之间存在一些差异。
Following Tim's instructions got me 90% of the way there, I just had to put my thinking cap on for 10 minutes to come up with this code instead..
按照 Tim 的指示让我完成了 90% 的工作,我只需要花 10 分钟的时间来思考这个代码。
timer values of 25 - 33 seem to work a lot better than 13ms for medium speed animations such as fading background images.
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);
}
};