2013-04-21 49 views
-1

下面有相當容易的功能,可以將圖像平滑地移動到其他位置。它來自遊戲,因此移動球員的圖像+30像素,例如移動地圖+30像素也是。如何使此Javascript功能更快(CPU密集度更低)

問題是所有的工作,除了它的緩慢。在我的現代CPU i7 930 2.8 Ghz其超平滑和快速,但在上網本與1.8 Ghz CPU非常緩慢。此外,在更好的但仍然低端的硬件上,這個功能是滯後的(圖像移動不那麼平滑),並且還需要更多時間來完成相同的移動。

如何讓這個函數減少CPU密集度?

var blokada = 0; 
var blokada2 = 0; 

function translate(elem, x, y, toff, loff, delay2) { 
    if (document.getElementById(elem) && blokada == 0) { 
     blokada = 1; 
     var elem = document.getElementById(elem); 
     var left = loff, 
      top = toff, 
      dx = x, 
      dy = y, //top - y, 
      i = 1, 
      count = delay2, 
      delay = delay2 * 2; 

     function loop() { 
      if (i >= count) { 
       blokada = 0; 
       return; 
      } 
      i += 1; 
      elem.style.left = (left - (dx * i/count)).toFixed(0) + 'px'; 
      elem.style.top = (top - (dy * i/count)).toFixed(0) + 'px'; 
      setTimeout(loop, delay); 
     } 
     loop(); 
    } 
} 

function translate2(elem, x, y, toff, loff, delay2) { 

    if (document.getElementById(elem) && blokada2 == 0) { 
     blokada2 = 1; 
     var elem = document.getElementById(elem); 

     var left = loff, 
      top = toff, 
      dx = left - x, 
      dy = top - y, 
      i = 1, 
      count = delay2, 
      delay = delay2; 

     function loop() { 
      if (i >= count) { 
       blokada2 = 0; 
       return; 
      } 
      i += 1; 
      elem.style.left = (left - (dx * i/count)).toFixed(0) + 'px'; 
      elem.style.top = (top - (dy * i/count)).toFixed(0) + 'px'; 

      setTimeout(loop, delay); 
     } 
     loop(); 
    } 
} 

translate2('player', x, y, 120, 120, 10); //5 
translate('map3', x, y, 0, 0, 10); 
+2

嘗試使用'Math.round()'或'| 0「(如果你不關心正確的子像素舍入)而不是'toFixed(0)'。此外,如果性能問題,則應使用[線性插值](http://en.wikipedia.org/wiki/Linear_interpolation),以便動畫始終採用相同的預定義時間長度(如果用戶計算機速度較慢,它只會在較少的幀中生成動畫)。如果您可以在http://jsfiddle.net或類似網站上重現最小工作版本,您也可以獲得更好的迴應。 – alex 2013-04-21 22:46:18

+0

我認爲這個問題最好在[CodeReview](http://codereview.stackexchange.com/)詢問 – Joseph 2013-04-21 22:56:13

+0

請在閱讀這個問題之前閱讀關於JavaScript優化的文章。有很多簡單的東西可以優化... – plalx 2013-04-21 22:57:48

回答

0

現在這應該至少比原來的速度快60%。因爲它預取elem.style,並且非常快地進行整數除法。它會用站不住腳的瀏覽器上工作過:)

var blokada = 0; 
var blokada2 = 0; 

function translate(elem, x, y, toff, loff, delay2) { 
var elem = document.getElementById(elem); // fetch once 
    if (elem && blokada == 0) { 
    blokada = 1; 
    var sty = elem.style; // fetch once use many... 
    // unnecessary assignments use loff and toff directly 
    // var left = loff, 
    // top = toff, 
    var dx = x, 
     dy = y, //top - y, 
     i = 1, 
     // unnecessary assignment 
     // count = delay2, 
     delay = delay2 * 2; 

    function loop() { 
     if (i >= delay2) { 
     blokada = 0; 
     return; 
     } 
     i += 1; 
     sty.left = (loff - (~~(dx * i/delay2))) + 'px'; 
     sty.top = (toff - (~~(dy * i/delay2))) + 'px'; 
     setTimeout(loop, delay); 
    } 
    loop(); 
    } 
} 

function translate2(elem, x, y, toff, loff, delay2) { 
var elem = document.getElementById(elem); // fetch once 
    if (document.getElementById(elem) && blokada2 == 0) { 
    blokada2 = 1; 
    // unnecessary assignments use loff and toff directly 
    // var left = loff, 
    // top = toff, 
    var sty = elem.style; // fetch once use many. 
     dx = loff - x, 
     dy = toff - y, 
     i = 1; 
     // unnecessary assignments 
     //count = delay2, 
     //delay = delay2; 

    function loop() { 
     if (i >= delay2) { 
     blokada2 = 0; 
     return; 
     } 
     i += 1; 
     sty.left = (loff -(~~(dx * i/delay2))) + 'px'; 
     sty.top = (toff -(~~(dy * i/delay2))) + 'px'; 

     setTimeout(loop, delay2); 
    } 
    loop(); 
    } 
} 

translate2('player', x, y, 120, 120, 10); //5 
translate('map3', x, y, 0, 0, 10); 
+0

這應該不會影響它,因爲它只在動畫的* setup *中完成一次。值得這樣做,但可能不是它緩慢的真正原因。 – alex 2013-04-21 22:58:49

+0

好主意,但刪除一個對getElementById的調用對整體性能的影響非常有限,速度非常快。 – RobG 2013-04-21 23:02:17

+0

@RobG,請現在休息一下。 – Ihsan 2013-04-21 23:22:22

3

如果您定位到現代瀏覽器,則可以使用css3 2d transform and translate()。保羅愛爾蘭有一個很好的解釋,爲什麼使用translate比絕對位置更好:http://paulirish.com/2012/why-moving-elements-with-translate-is-better-than-posabs-topleft/

您的代碼應該是這樣的:

var transform = "translate(" + left + "px," + top + "px)"; 
element.style.transform = transform; 
element.style['-webkit-transform'] = transform; 
element.style['-ms-transform'] = transform;