A little background: I'm currently working on a project that contains about 20-30 items with linear gradients which animate their stops continuously throughout the entire run time of the experience.
As the site runs, the framerate drops continuously over time. Running the chrome dev tools timeline shows an insane amount of requestAnimationFrame
calls from this library; more and more over time, thus the consistent drop in framerate. So much so that the chrome dev tools buffer fills up in a few seconds.
Here is my code:
var colors;
var fnAnimate;
var gradient;
var s1;
var s2;
var s3;
var stops;
colors = ['#EFFF22', '#D1FBFF', '#2759FF'];
gradient = draw.gradient('linear', function(stop) {
s1 = stop.at(0, colors[0]);
s2 = stop.at(0.4, colors[1]);
s3 = stop.at(1, colors[2]);
stops = [s1, s2, s3];
});
fnAnimate = function() {
var color;
var stop;
color = _.sample(colors);
stop = _.sample(stops);
stop.animate().update({
color: color
});
};
setInterval(function() {
fnAnimate();
}, 1000);
From my understanding of the documentation, each invocation of animate on an object should stop any preexisting animation on said object. Checking here in the source, that does seem to be the case. If you look closer at the stop
method, it looks to clear an animation timeout and delete/reset some properties. It is not doing, however, one vital thing.
Looking through the fx.render
method, on lines 189 and 192, we enter a requestAnimationFrame
loop. This is good. BUT after looking around this entire library, cancelAnimationFrame is nowhere to be found. There's also an absence of a shim for it in the helpers.js
next to the requestAnimationFrame
shim.
Essentially what is happening is that every time animate
is called, a requestAnimationFrame
loop is created, but never killed, nor a reference to it stored; thus creating zombie animation loops. This would explain the extreme amount of requestAnimationFrame
calls I'm seeing in my dev tools timeline.