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.
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.
Share Improve this question edited Mar 4, 2016 at 13:57 Nick asked Dec 16, 2014 at 9:32 NickNick 3,2812 gold badges30 silver badges52 bronze badges 7- Did you look at Chrome DevTools ? See developer.chrome./devtools/docs/timeline and stackoverflow./a/16752638/827168 for more info – pomeh Commented Dec 16, 2014 at 9:42
- 2 @pomeh Yes I did, but I can't see which CSS animation is using a lot CPU – Nick Commented Dec 16, 2014 at 9:52
- I tried this earlier, but then moved on and profiled the website by disabling two of the three animations, three times. – cnvzmxcvmcx Commented Dec 16, 2014 at 13:34
- 1 CSS Animations use GPU cycles, not CPU cycles. A regular JavaScript profiler should give you execution time and CPU usage, but since there's a pletely different mechanism at work for CSS animations, these profilers aren't what you need. The whole point of CSS animations is that they're hardware accelerated meaning that the CPU isn't the main driver behind them. – Josh Burgess Commented Dec 18, 2014 at 21:58
- 1 use the OS task meter; it doesn't care what the cause is or how the work is performed, just how much of it. – dandavis Commented Dec 24, 2014 at 22:00
4 Answers
Reset to default 2Click 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)
Maybe you could you console.profile() with Firefox. http://www.stoimen./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./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./wiki/index.php/Console.profile
Preface: This is not a "plete" answer, as such, but rather the best I could e 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 cheapc
is several times more expensive thana
orb
.
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 ton.fx.tick
- Chromium:
b
spent 40ms non-idle; Firefox: 4 calls ton.fx.tick
- Chromium:
c
spent 130ms non-idle; Firefox: 36 calls ton.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./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
plete: -> log 'a', .5
$('#test_b').animate {top: '100px', left: '100px', opacity: 0.3, width: '500px'},
duration: 200
step: -> b += 1
plete: -> log 'b', 2
$('#test_c').animate {left: '500px', top: '300px', opacity: .75, height: '50px', width: '400px'},
duration: 3000
step: -> c += 1
plete: -> log 'c', 3
$(document).ready -> setTimeout go, 500
And the same JS piled 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;
},
plete: 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;
},
plete: 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;
},
plete: function() {
return log('c', 3);
}
});
};
$(document).ready(function() {
return setTimeout(go, 500);
});
}).call(this);
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./ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="1"></div>
<br>
<div id="2"></div>