Profile specific animation CPU

这一生的挚爱 提交于 2019-11-29 05:10:02

问题


The situation & problem
I have multiple animations (css and javascript/jQuery) in my site and sometimes it makes my site stutter.

My question
How can I see how much cpu a specific animation (both CSS, JavaScript and jQuery) uses in runtime and execution time

I know how I can see the entire site CPU usage but not for a specific animation.


回答1:


Click F12, Go to profiles, click on start. Reload page.

Wait untill your page reloaded, and click stop.

Click on your profile and see result (Y)




回答2:


Preface: This is not a "complete" answer, as such, but rather the best I could come up within a reasonable amount of time. It seemed a shame to not post my results even though they're not a perfect answer...

It also only covers jQuery.animate; I did not investigate CSS animations.


For jQuery, at least, this is difficult; it's not like the browser "knows" about a jQuery animation. Effectively, all jQuery does is schedule a function to run n times with setTimeout() or setInterval(), where each function call moves the element by a few pixels (or changed something else a little bit), giving the illusion of smooth animations.

Your browser would, somehow, have to keep track of which function call belongs to which animation. Since these are anonymous functions, this is not really easy... Some sort of special debugging statement could be used, but AFAIK no browser implements a feature like this.

What we can do is measure the number of updates jQuery.animate does with the step callback:

A function to be called for each animated property of each animated element. This function provides an opportunity to modify the Tween object to change the value of the property before it is set.

This will only give you an approximation, at best. But perhaps it's good enough; I've created an example (see below), which gives me these results on my system:

"a: 52 updates; 26 upd/s"
"b: 27 updates; 54 upd/s"
"c: 1080 updates; 360 upd/s"

Your system might vary, but suggests that:

  • a was the cheapest;
  • b was slightly more exensive, but also actually quite cheap
  • c is several times more expensive than a or b.

To check if this is roughly accurate, I enabled only one animation at a time, and checked if this corresponds to what Chromium & Firefox developer tools report:

  • Chromium: a spent 40ms non-idle; Firefox: 2 calls to n.fx.tick
  • Chromium: b spent 40ms non-idle; Firefox: 4 calls to n.fx.tick
  • Chromium: c spent 130ms non-idle; Firefox: 36 calls to n.fx.tick

Which is indeed roughly accurate, though not entirely.

Will this be useful enough for your application? I have no idea. Maybe, maybe not...



Test HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Animations test</title>
        <style>
            div { width: 200px; height: 100px; position: relative; color: #fff; }
            #test_a { background-color: green; }
            #test_b { background-color: red; }
            #test_c { background-color: blue; }
        </style>
    </head>

    <body>
        <div id="test_a"></div>
        <div id="test_b"></div>
        <div id="test_c"></div>

        <script src="http://code.jquery.com/jquery-2.1.1.min.js"></script>
        <script src="anim.js"></script>
    </body>
</html>

Test JS in CoffeeScript:

go = ->
    a = b = c = 0

    log = (n, t) ->
        eval "u = #{n}"
        str = "#{n}: #{u} updates; #{parseInt u / t, 10} upd/s"
        $("#test_#{n}").html str
        console.log str

    $('#test_a').animate {left: '500px'},
        duration: 500
        step: -> a += 1
        complete: -> log 'a', .5

    $('#test_b').animate {top: '100px', left: '100px', opacity: 0.3, width: '500px'},
        duration: 200
        step: -> b += 1
        complete: -> log 'b', 2

    $('#test_c').animate {left: '500px', top: '300px', opacity: .75, height: '50px', width: '400px'},
        duration: 3000
        step: -> c += 1
        complete: -> log 'c', 3

$(document).ready -> setTimeout go, 500

And the same JS compiled for convenience:

// Generated by CoffeeScript 1.7.1
(function() {
  var go;

  go = function() {
    var a, b, c, log;
    a = b = c = 0;
    log = function(n, t) {
      var str;
      eval("u = " + n);
      str = "" + n + ": " + u + " updates; " + (parseInt(u / t, 10)) + " upd/s";
      $("#test_" + n).html(str);
      return console.log(str);
    };
    $('#test_a').animate({
      left: '500px'
    }, {
      duration: 500,
      step: function() {
        return a += 1;
      },
      complete: function() {
        return log('a', .5);
      }
    });
    return;
    $('#test_b').animate({
      top: '100px',
      left: '100px',
      opacity: 0.3,
      width: '500px'
    }, {
      duration: 200,
      step: function() {
        return b += 1;
      },
      complete: function() {
        return log('b', 2);
      }
    });
    return $('#test_c').animate({
      left: '500px',
      top: '300px',
      opacity: .75,
      height: '50px',
      width: '400px'
    }, {
      duration: 3000,
      step: function() {
        return c += 1;
      },
      complete: function() {
        return log('c', 3);
      }
    });
  };

  $(document).ready(function() {
    return setTimeout(go, 500);
  });

}).call(this);



回答3:


Maybe you could you console.profile() with Firefox. http://www.stoimen.com/blog/2010/02/02/profiling-javascript-with-firebug-console-profile-console-time/

Put console.profile() before the function you want to measure and console.profileEnd() after the method.

<html>
  <body>
    <script>
      myFunc = function() {
        var a = [];
      }             

      console.profile();
      myFunc();
      console.profileEnd();
    </script>
  </body>
</html>

https://developer.chrome.com/devtools/docs/console-api Here you find some more methods for debugging.

Edit: I've just found another site with useful information for the firebug extension: https://getfirebug.com/wiki/index.php/Console.profile




回答4:


You can try running a console.profile() instance at the start of each jQuery animation and then disable animations one at a time to debug.

You cannot profile CSS animations as far as I know. Only the starting and ending values are accessible via JavaScript.

function AnimateRotate(elem, angle, dur) {
  var $elem = $(elem);

  // we use a pseudo object for the animation
  // (starts from `0` to `angle`), you can name it as you want
  $({
    deg: 0
  }).animate({
    deg: angle
  }, {
    duration: dur,
    step: function(now) {
      // in the step-callback (that is fired each step of the animation),
      // you can use the `now` paramter which contains the current
      // animation-position (`0` up to `angle`)
      $elem.css({
        transform: 'rotate(' + now + 'deg)'
      });
    }
  });
}

$('#1').click(function() {
  console.profile('Animation #1');
  $(this).animate({
    'height': '100px',
    'width': '100px'
  }, function() {
    console.profileEnd('Animation #1');
  });
});

$('#2').click(function() {
  console.profile('Animation #2');
  AnimateRotate(this, 3000, 400);
  $(this).animate({
    'height': '300px',
    'width': '300px'
  }, function() {
    console.profileEnd('Animation #2');
  });
});
div {
  height: 10px;
  width: 10px;
  background-color: red;
  transform-origin: 60% 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="1"></div>
<br>
<div id="2"></div>


来源:https://stackoverflow.com/questions/27501392/profile-specific-animation-cpu

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!