I am facing high CPU usage (30 to 40%) when calling recursively requestAnimationFrame
, does anyone has good strategies to lower it down?
Simple example:
var canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 20;
var canvasContext = canvas.getContext('2d');
document.body.appendChild(canvas)
var rafId;
function drawLoop(time) {
canvasContext.clearRect(0, 0, 100, 20);
canvasContext.fillRect(0, 0, Math.random() * 100 * 1.4, 20);
rafID = window.requestAnimationFrame(drawLoop);
}
drawLoop();
To optimize system and browser resources, it is recommended to use requestAnimationFrame , which requests the browser to execute the code during the next repaint cycle. This allows the system to optimize resources and frame-rate to reduce unnecessary reflow/repaint calls.
requestAnimationFrame() is much more efficient than setTimeout() or setInterval() , and the result is smoother and more accurate (just check the provided demo and the consumed CPU).
I cannot get this example to do anything to my CPU worth mentioning, but I did manage to get it down by employing these two methods. My CPU was running at about 4-5% running your snippet, by running save / restore on the context that shaved off 2%.Unsure why - because we haven't made any transformations. The latter example just uses the old hacker way of doing this by resetting the canvas.width - this wipes the entire canvas context each time - and should be more expensive - however it got this example down to 1.4%
var canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 20;
var canvasContext = canvas.getContext('2d');
document.body.appendChild(canvas)
var rafId;
function drawLoop(time) {
canvasContext.save();
canvasContext.clearRect(0, 0, 100, 20);
canvasContext.fillRect(0, 0, Math.random() * 100 * 1.4, 20);
canvasContext.restore();
rafID = window.requestAnimationFrame(drawLoop);
}
drawLoop();
var canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 20;
var canvasContext = canvas.getContext('2d');
document.body.appendChild(canvas)
var rafId;
function drawLoop(time) {
canvas.width = canvas.width;
canvasContext.fillRect(0, 0, Math.random() * 100 * 1.4, 20);
rafID = window.requestAnimationFrame(drawLoop);
}
drawLoop();
Now I would need to go into more performance exploration to find out why, or if it actually does anything at all.
However you could employ a different drawing technique, such as just moving a sprite or a mask back and forth over some bitmap data, that will make this much less hard for the renderer to handle. I will not post that here as it goes beyond the scope of this question.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With