Reputation: 1240
I just reimplemented a component of a music app I'm working on to use KineticJS instead of my prototype GUI done all with DOM elements and some JQuery animations. At first I was happy to see a modest 10-15% improvement in framerate in Chrome, but then tested on iPad 2 and I'm getting I would estimate about 6fps compared to the DOM version around 30fps.
I must be doing something wrong. I hope.
The component is 1000x300, and has 2 layers. One is static background, the other has ~150 shapes, most about 20-30px in size, a few running the length of the canvas. Animations are using Kinetic.Tween to simultaneously animate opacity and width. The majority of shapes are just circles, small in size. Nothing is cached, but this seems like so few and so simple shapes that I wouldn't have expected such sluggishness (I estimate around 6 fps is what I'm seeing). I am creating new Tween instances for individual notes, and could instead use a pool since the number of total objects is constant, but I'm surprised if that alone is causing such a slow down. Intuitively I suspect its pushing pixels that is somehow the problem?
The app is using WebAudio and JQuery UI for simple widgets like buttons, but has at least 30 fps with the DOM implementation with same audio, same everything else.
With Tweens, what is the default behavior of the rendering loop? I see no way in the docs to specify a desired framerate. Kinect.Animation looks like it offers finer grain control but in my case this would require way too much state, as the animations are all just impulse events that fade away over 0.5-1.2 seconds. Is opacity for some reason extremely expensive to animate? Is my static background layer causing any issue by not being cached as an image?
Sorry no code to show. I could create a jsfiddle but I'm hoping there's something obvious in the above description that I should do differently.
Oh and I'm not looking up the animated objects; they're all held in arrays from init time. Again, wouldn't think that would be the issue.
Upvotes: 2
Views: 237
Reputation: 1240
Since no one has dared comment on my awesome and important question, I'll post an answer. I'm not certain, but I believe the first version of my code was not correctly setting the viewport scaling in the HTML, resulting in a non-GPU scaled canvas and hence terrible framerate.
If anyone else hits a similar problem, it may be you forgot to add this to the HEAD of your HTML:
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
Though there's other options for setting the scale, I prefer this, and then doing any custom screen width scaling within my app's code.
ps. I now have a healthy 40-50fps with lots of animated transparent fades and whatnot on my aging iPad 2 using KinectJS.
Upvotes: 7