如何使这个Javascript函数更快(CPU密集度更低)

时间:2013-04-21 22:44:13

标签: javascript optimization

下面有相当简单的功能,可以将图像平滑移动到其他位置。它来自游戏,因此移动玩家的图像+30像素,例如移动地图+30像素。

除了缓慢之外,问题全部都在起作用。在我的现代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);

3 个答案:

答案 0 :(得分:3)

如果您定位现代浏览器,则可以使用css3 2d transform and 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;

答案 1 :(得分: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);

答案 2 :(得分:0)

查看requestAnimationFrame(http://paulirish.com/2011/requestanimationframe-for-smart-animating/)它真的加快了我之前做过的javascript动画。它基本上意味着您可以停止使用setTimeout并让浏览器决定何时最好计算并绘制下一帧。