我正在编写一个脚本,用户可以在其中选择一系列数据,然后从服务器中获取一堆图像(超过150张),然后循环通过它们来制作电影。我想知道的是在移动图像槽时加载防止滞后的最有效方法。
目前,我正在使用Ajax从服务器获取图像,并将其存储在JavaScript上的Image对象数组中。在HTML中,我有一个div标签,希望在其中放置图像。在数组中创建所有Image对象(并设置其适当的src)后,我将执行以下操作:
imgElem = document.createElement('img'); document.getElementById('loopLocation').appendChild(imgElem); imgElem.src = images[0].src;
之后,我只做最后一个调用,但是更改了循环索引。我每400毫秒执行一次。循环有效,但有时会滞后,并在图像上冻结的时间更长。我想知道我是否能够从客户端改进此功能,或者只需要响应速度更快的服务器即可。
您可能想要考虑将所有图像整合为一张大图像的拼版。这样,您只需要加载一个大图像,然后为每个场景重新定位即可。
或者,您可能还需要在实际使用之前预加载这150张图像。您可以使用JS数组存储Image对象,然后遍历该数组以获取图片。
var images = []; var expectLoaded = 150; for(var i = 0; i<expectLoaded;i++){ (function(i){ //new image object var img = new Image(); //onload hander img.onload = function(){ //after load, push it into the array images.push[img]; //and check if the all has loaded if(images.length === expectLoaded){ //preload done } } //start loading this image img.src = //path to image[i]; },(i)); }
循环会阻塞UI线程。JS是单线程的,这意味着代码以线性方式执行,一个接一个地执行。该循环语句之后的所有内容都将等待,直到循环完成。如果该循环需要很长时间…请喝杯咖啡。另外,由于您正在处理DOM,因此由于UI线程被阻止,您看不到更改。
但是有很多方法可以绕开它,其中一种方法是使用超时来延迟和排队代码,以便在JS不忙时执行。
function animate(frameNo){ //animate frame[frameNo]; if(frameNo < total_frames){ //make the UI breate in between frames setTimeout(function(){ //so that changes reflect on the screen animate(++frameNo); //then animate next frame },200); } } //start animate(0);