2013-01-07 68 views
3

我正在一個Web藝術項目,需要許多對象淡入和淡出在特定的時間間隔(我希望使用100個或更多的對象)。我有jQ讀取包含元數據的XML文件,並將Ps附加到主體,然後根據元數據中的信息告知其淡入和淡出。我使用setTimeouts來實現這一點。JS/jQ更有效的方式來處理大量的setTimeouts

這件作品最終會非常耗費資源。在頁面加載一兩分鐘後,我的機器開始喘息。 (或者,我認爲它可能不是一個資源問題,而是一個圖形化的問題。)

有沒有人有一些建議,使這更資源友好/高效?我感謝任何幫助!

這裏的活鏈接:http://justwhatdoyoucallthis.com/trynottogiveup/(當心資源豬)

下面是相關的腳本:

$.ajax({ 
    type: 'get', 
    url: 'problems.xml', /* ...which contains like 99 problems */ 
    dataType: 'xml', 
    success: function(problems) { 
     $(document).ready(function() { 
      var winWidth=$(window).width(); 
      var winHeight=$(window).height(); 
      $(problems).find('problem').each(function() { 
       var probType=$(this).attr('type'); 
       var probAppear=$(this).attr('appear'); 
       var probName=$(this).children('name').text(); 
       var probID=(probName.replace(/\s/g, '')).toLowerCase(); 
       var probIntensity=($(this).children('intensity').text()+5)*10; 
       var probInterval=$(this).children('interval').text(); 
       var probDuration=$(this).children('duration').text(); 
       var ranLeft=Math.random()*winWidth-(probIntensity/2); 
       var ranTop=Math.random()*winHeight-(probIntensity/2); 
       $('body').append('<p id="'+probID+'" class="'+probType+'" style="left: '+ranLeft+'px; top: '+ranTop+'px; height: '+probIntensity+'px; width: '+probIntensity+'px;"><span>'+probName+'</span></p>'); 
       (function showLoop() { 
        if(probAppear=='fade') { var fadeInDuration=1000; } else { var fadeInDuration=0; } 
        $('#'+probID).delay(probInterval*1000).fadeIn(fadeInDuration).delay(probDuration*1000).fadeOut(1000); 
        setTimeout(showLoop, 1000); 
       })(); 
      }); 
     }); 
    } 
}); 
+0

適用於Core i5/Linux 64位,firefox 17. BUt我認爲一般使用jQuery動畫操縱一堆DOM元素無論如何都會佔用資源。可能是Canvas在這些事情上更有效率。 – hayavuk

+0

您可以隨時嘗試查看更改全局間隔值是否有助於您。 '$ .fx.interval = 50;'。從jQuery 1.8開始,默認值是13。 50仍然有一個平穩過渡,並會節省你一些CPU的強度。提高和降低它,直到找到適合您的動畫的東西。這不是傻瓜證明。 – Ohgodwhy

回答

1

這裏是你的代碼的優化版本,但像bvukelic說,整個概念很可能是更高效的畫布。

我在代碼中看到的問題是,延遲和淡入淡出操作確實是同步調用的,但是超時是異步執行的,這意味着在一段時間後,對同一對象有多個操作流(並且這一百次)。

所以解決方法是將重複的超時作爲回調附加到.fadeOut()動作。

$(function() { 
    var $win = $(window), 
     winWidth = $win.width(), 
     winHeight = $win.height(), 
     showLoop = function(prob) { 
      var fadeInDuration = prob.appear == 'fade' ? 1000 : 0; 
      $('#'+prob.id) 
       .delay(prob.interval*1000) 
       .fadeIn(fadeInDuration) 
       .delay(prob.duration*1000) 
       .fadeOut(1000, function() { 
        window.setTimeout(function() { 
         showLoop(prob); // synchronously repeated callback 
        }, 1000); 
       }); 
     }; 

    $.ajax({ 
     type: 'get', 
     url: 'problems.xml', /* ...which contains like 99 problems */ 
     dataType: 'xml', 
     success: function(problems) {   
      $('problem', problems).each(function() { 
       var $t = $(this), 
        probName = $('name', this).text(), 
        prob = { 
         type: $t.attr('type'), 
         appear: $t.attr('appear'), 
         name: probName, 
         id: probName.replace(/\s/g, '').toLowerCase(), 
         intensity: (parseInt($('intensity', this).text()) + 5) * 10, 
         interval: parseInt($('interval', this).text()), 
         duration: parseInt($('duration', this).text()), 
         pos: { 
          top = Math.random()*winHeight-(prob.intensity/2), 
          left = Math.random()*winWidth-(prob.intensity/2) 
         } 
        }; 

       $('<p>') 
        .append('<span>'+prob.name+'</span>') 
        .attr('id', prob.id) 
        .addClass(prob.type) 
        .width(prob.intensity) 
        .height(prob.intensity) 
        .css({ 
         top: prob.pos.top, 
         left: prob.pos.left, 
        }) 
        .appendTo('body'); 

       showLoop(prob); 
      }); 
     } 
    }); 
}); 
+0

我剛剛從這裏學到了很多關於javascript的知識。該頁面像冠軍一樣運行,我明白爲什麼。謝謝! –

+0

我很高興我可以幫助你:) – Simon

+0

我真的很想看到這個項目,所以你可以發佈一個網絡鏈接,如果或只要你有它在線? – Simon

相關問題