下面的脚本存在严重的视觉和性能问题。最大的问题是,对象的动画变得非常粗糙,在IE9中几乎是如此,但在火狐中却越来越烦人。
直到最近,它的速度还相当快--但我担心复杂性正在减缓。奇怪的是,在我的Sunspider基准实例中,IE9运行速度比火狐快。
脚本(它是更大集合的片段*):
我的代码有明显的速度改进吗?有相当多的回报,我该怎么减少呢?有没有我错过的无限循环?有软件可以用来分析JS的慢点吗?
*(我不能提供其他JS文件或HTML,但我发现这个脚本是问题所在)
更新:经过更多的测试后,的step动画功能--通过scrollLeft跟踪窗口中的对象--导致了动画的抖动。移除它会大大改善事物。
然而,这并不是一个可行的长期解决方案。一个快速的修复方法是在complete上调用下面的函数,但是对于最终用户来说,这是一种不太顺利的体验,特别是当对象移动更远的距离时。
那么,我如何修改step函数来运行“更慢”/更高效呢?,我猜这是因为它使用了所有可用的资源,每毫秒跟踪对象一次。
(function ($) {
sessionStorage.gameMainStage = 0
moveShip = function() {
switch (sessionStorage.gameMainStage)
{
case '1':
$("#object").animate(
{ crSpline: $.crSpline.buildSequence([[715, 425], [582, 524], [556, 646], [722, 688], [963, 629], [1143, 467]]) },{
duration: 10000,
step: function() {
var mover = $('#object'),
posX = mover.position().left;
posY = mover.position().top;
$(window)
.scrollLeft(posX - $(window).width() / 2)
.scrollTop(posY - $(window).height() / 2);
},
complete: function() {
$.colorbox({href:"dialog-1.html", width:"737px", height:"474px", iframe: true, overlayClose: false, escKey: false, close: ""});
}
}
);
break;
case '2':
$("#object").animate(
{ crSpline: $.crSpline.buildSequence([[1143, 467], [1343, 667], [1443, 367], [1243, 167], [1499, 285]]) },
{
duration: 5000,
step: function() {
var mover = $('#object'),
posX = mover.position().left;
posY = mover.position().top;
$(window)
.scrollLeft(posX - $(window).width() / 2)
.scrollTop(posY - $(window).height() / 2);
},
complete: function() {
$.colorbox({href:"dialog-2", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""});
}
}
);
break;
case '3':
$("#object").animate(
{ crSpline: $.crSpline.buildSequence([[1499, 285], [1922, 423]]) },
{
duration: 5000,
step: function() {
var mover = $('#object'),
posX = mover.position().left;
posY = mover.position().top;
$(window)
.scrollLeft(posX - $(window).width() / 2)
.scrollTop(posY - $(window).height() / 2);
},
complete: function() {
$.colorbox({href:"dialog-3.html", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""});
}
}
);
break;
case '4':
$("#object").animate(
{ crSpline: $.crSpline.buildSequence([[1922, 423], [2216, 578]]) },{
duration: 5000,
step: function() {
var mover = $('#object'),
posX = mover.position().left;
posY = mover.position().top;
$(window)
.scrollLeft(posX - $(window).width() / 2)
.scrollTop(posY - $(window).height() / 2);
},
complete: function() {
$.colorbox({href:"game-1.html", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""});
}
}
);
break;
case '5':
$("#object").animate(
{ crSpline: $.crSpline.buildSequence([[2216, 578], [2769, 904]]) },{
duration: 5000,
step: function() {
var mover = $('#object'),
posX = mover.position().left;
posY = mover.position().top;
$(window)
.scrollLeft(posX - $(window).width() / 2)
.scrollTop(posY - $(window).height() / 2);
},
complete: function() {
$.colorbox({href:"dialog-4.html", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""});
}
}
);
break;
case '6':
$("#object").animate(
{ crSpline: $.crSpline.buildSequence([[2769, 904], [3263, 903]]) },{
duration: 5000,
step: function() {
var mover = $('#object'),
posX = mover.position().left;
posY = mover.position().top;
$(window)
.scrollLeft(posX - $(window).width() / 2)
.scrollTop(posY - $(window).height() / 2);
},
complete: function() {
$.colorbox({href:"dialog-5.html", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""});
}
}
);
break;
case '7':
$.colorbox({href:"game-2.html", width:"500px", height:"600px", iframe: true, overlayClose: false, escKey: false, close: ""});
break;
case '8':
$.colorbox({href:"dialog-6.html", width:"737px", height:"567px", iframe: true, overlayClose: false, escKey: false, close: ""});
break;
case '9':
$("#object").animate(
{ crSpline: $.crSpline.buildSequence([[3263, 903], [4141, 820]]) },{
duration: 5000,
step: function() {
var mover = $('#object'),
posX = mover.position().left;
posY = mover.position().top;
$(window)
.scrollLeft(posX - $(window).width() / 2)
.scrollTop(posY - $(window).height() / 2);
},
complete: function() {
$.colorbox({href:"dialog-7.html", width:"737px", height:"547px", iframe: true, overlayClose: false, escKey: false, close: ""});
}
}
);
break;
case '10':
$("#object").animate(
{ crSpline: $.crSpline.buildSequence([[4141, 820], [4568, 949], [4447, 1175]]) },{
duration: 5000,
step: function() {
var mover = $('#object'),
posX = mover.position().left;
posY = mover.position().top;
$(window)
.scrollLeft(posX - $(window).width() / 2)
.scrollTop(posY - $(window).height() / 2);
},
complete: function() {
$.colorbox({href:"dialog-8.html", width:"737px", height:"434px", iframe: true, overlayClose: false, escKey: false, close: ""});
}
}
);
break;
case '11':
$.colorbox({href:"dialog-9.html", width:"737px", height:"567px", iframe: true, overlayClose: false, escKey: false, close: ""});
break;
case '12':
$("#object").animate(
{ crSpline: $.crSpline.buildSequence([[4447, 1175], [4701, 1124], [4816, 822]]) },{
duration: 5000,
step: function() {
var mover = $('#object'),
posX = mover.position().left;
posY = mover.position().top;
$(window)
.scrollLeft(posX - $(window).width() / 2)
.scrollTop(posY - $(window).height() / 2);
},
complete: function() {
$.colorbox({href:"dialog-10.html", width:"900px", height:"687px", iframe: true, overlayClose: false, escKey: false, close: ""});
}
}
);
break;
}
};
})(jQuery);
发布于 2012-10-26 21:10:52
我在一个连接到window.resize和window.scroll的页面应用程序中遇到了这个问题。在IE上,它似乎比其他浏览器慢得多。
我注意到的第一件事是,在IE中,附加到window.scroll或.resize的回调在调整窗口大小(或滚动)时,似乎比Chrome或FF激发的次数多了很多倍。因此,任何附加的回调都是Chrome的多倍调用,从而增加了其相对成本。
我们设法通过将这些回调中所做的事情最小化到最小来解决我们的问题,我们获得的主要好处是摆脱了jQuery选择器。因此,在您的示例中,您的回调函数中有var mover = $('# object '),每次事件触发时,IE将尝试查找并获取对象并将其包装在jQuery中,只需在回调之外执行一次,然后使用缓存的对象。在我们的例子中,这提高了性能的数量级,即使没有遇到性能问题,这似乎也是一件好事(这是一个不必要地重复的操作)。
因此,例如,在第8种情况下,有如下内容:
case '10':{
//caching myObject once and then use it afterwards
var myObject = $("#object"),
$window = $(window);
myObject.animate(
{
crSpline: $.crSpline.buildSequence([[4141, 820], [4568, 949], [4447, 1175]]) },
{
duration: 5000,
step: function() {
var mover = myObject, //no need to refetch the object
posX = mover.position().left;
posY = mover.position().top;
$window.scrollLeft(posX - $window.width() / 2)
.scrollTop(posY - $window.height() / 2);
},
complete: function() {
$.colorbox({href:"dialog-8.html", width:"737px", height:"434px", iframe: true, overlayClose: false, escKey: false, close: ""});
}
}
);
}
ps:另外,我不确定您的应用程序的语义,但是您可能需要添加自己的逻辑来跟踪posX和posY,因为它们总是可以引用原始缓存对象,但是在所有情况下,都要执行我提到的步骤,以确保选择器的成本是导致问题的原因(就像在我的例子中一样)。
发布于 2012-10-21 19:45:54
恐怕你所用的图书馆太旧了,不能指望有很好的性能。
我不认为您的代码有什么问题(除了您可以为每个开关用配置参数使用一个函数,但这只是一个重构问题,不会对性能产生显著影响)。
CrSpline使用左和顶CSS属性。
您可能需要研究利用硬件加速的CSS 2d转换:
使用-webkit/moz/ms-transform: translateX(-1000px) translateY(200px)
而不是left: -1000px; top: 200px;
我认为您可以很容易地向这个方向重写cr样条库中的一些代码。
你也可以尝试寻找一个最新的“样条”库。
另外一点: crSpline似乎没有使用requestAnimationFrame特性。JQuery的animate
方法也没有。我建议你看看TweenLite/TweenMax库:http://www.greensock.com/v12/
为你的工作干杯!
发布于 2012-10-21 19:50:11
首先,您应该优化您的代码,为您的动画创建一个函数(没有测试,但应该有效):
function animateMyObjet(duration,sequence,callback)
{
$("#object").animate(
{ crSpline: $.crSpline.buildSequence(sequence),
{
duration: duration,
step: function() {
var mover = $('#object'),
posX = mover.position().left;
posY = mover.position().top;
$(window)
.scrollLeft(posX - $(window).width() / 2)
.scrollTop(posY - $(window).height() / 2);
},
complete: function() {
callback();
}
}
}
在代码中调用如下所示:
switch (sessionStorage.gameMainStage)
{
case '1': animateMyObjet(10000,[[715, 425], [582, 524], [556, 646], [722, 688], [963, 629], [1143, 467]],
function() {
$.colorbox({href:"dialog-1.html", width:"737px", height:"474px", iframe: true, overlayClose: false, escKey: false, close: ""});
break;
case '2' : ...
}
第二,几周前,我发现网页元素的数量影响着IE9的性能。尝试隐藏由于可滚动容器而不需要的所有元素,比如隐藏的元素。
有时,屏幕上可见元素的数量也会影响到动画的表现。对于测试,尝试缩小浏览器窗口的大小并播放您的动画。我很肯定动画会更流畅。
我希望这些建议能对你有所帮助。如果你解决了你的问题,别忘了发布你的最终解决方案!
最后,查看有关IE9性能问题的潜在相关主题:IE9 :我的网站上的CPU利用率总是很小。
https://stackoverflow.com/questions/12978069
复制相似问题