在一个网站上,我有一个滑块(我使用jQuery UI的滑块),用于控制图像序列。图像在页面的背景中全屏显示(我使用的是background-size: cover)。在我的开发电脑上,它工作得很好,但当我在功能不那么强大的电脑上试用时,它就变慢了。
我做序列的方式很简单。下面是我的一些代码,可以让你大致了解我在做什么。(我认为代码对我的问题来说不是必不可少的,但我还是添加了它……请随意跳过!)
HTML:<div id="animation">
<div class="frame frame0"></div>
<div class="frame frame1"></div>
<div class="frame frame2"></div>
[...]
<div class="frame frame20"></div>
</div>
CSS: #animation {
height: 100%;
position: relative;
width: 100%;
}
#animation div.frame {
background-position: center center;
background-size: cover;
bottom: 0;
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: 1;
}
#animation div.frame.active { z-index: 2; }
#animation div.frame0 { background-image: url(frame0.jpg); }
#animation div.frame1 { background-image: url(frame1.jpg); }
[...]
#animation div.frame20 { background-image: url(frame20.jpg); }
jQuery: var $frames = $('#animation').find('div.frame');
$('#slider').slider({
value: 1,
min: 1,
max: 21,
step: 1,
slide: function(event, ui){
$frames.removeClass('active').filter(':eq(' + (ui.value - 1) + ')').addClass('active');
}
});
通过测试不同的东西,我设法隔离它在Chrome中导致性能问题的原因。罪魁祸首是背景大小的封面。只要我删除background-size属性并使用图像的默认大小,我就几乎没有延迟。
当我使用background-size: cover并且我的图像与我的Chrome窗口大小相同时,性能会更好。但是,相对于原始图像大小,图像拉伸(或压缩)越大,我得到的延迟就越大。
到目前为止,我唯一要优化的是使用不同的图像大小,并使用JavaScript加载更接近浏览器窗口大小的序列,并希望它不会延迟。这意味着,如果用户调整浏览器窗口的大小,我可能不得不重新加载另一个图像工具包。
任何想法我可以优化图像序列在Chrome获得更好的性能?
我今天做了一个测试,使用画布代替每个框架的HTML元素列表。它在Chrome中产生了非常好的性能。画布解决方案的缺点是它在IE8中不起作用,但对于这个项目,我们在Chrome上的用户比在IE8上的用户多得多,所以我可以忍受。
这对我的画布绘制很有帮助:HTML5中的逐帧动画
剩下的就是简单地修改滑动块上的画布,而不是添加和删除活动类。
var arrFrames = [];
for(var i = 0; i < 21; i++){
arrFrames[i] = new Image();
arrFrames[i].onload = function() { /* check that all images are loaded before allowing the animation on the slider */ }
arrFrames[i].src = 'frame' + i + '.jpg';
}
$('#slider').slider({
value: 0,
min: 0,
max: 20,
step: 1,
slide: function(event, ui){
/* Calculate image size and ratio */
ctx.clearRect(0, 0, iCanvasWidth, iCanvasHeight);
ctx.drawImage(arrFrames[ui.value], 0, 0, iWidth, iHeight);
}
});
我没有把所有的变量定义都放在代码中,以保持简短和干净,但是变量名应该足够清楚,以便理解它们具有什么值。
我意识到一件重要的事情:不要忘记在javascript中设置画布的宽度和高度。