The answer is simple:
Do not use binding and the component life cycle if you want smooth animations.
Binding is a convenience but it is bad for performance.
The component invalidation cycle is designed to save the CPU not to make animations smooth.
Horses for courses :-)
But there is no way to avoid binding if I want to tween x, y, z, alpha, width, height, etc. on UIComponents.
If I could say "don't dispatch binding events when I set thisProperty to true", that would help a lot. I could do that if I could customize the Bindable generated code.
Any other ideas?
1 person found this helpful
I see. You are animating a component, rather than the contents of a component.
Seeing as there is a lot of stuff going on when you move components and their children then this really isn't a choice if you want a performance.
If you look at Tinks Efflex framework (www.efflex.org) he gets round this by using an animation layer and caching the component as a bitmap whilst it is animated. This can create very sooth transitions and effects.
Hope that helps
Cool, that's a great option, I'll check out his effects again. I would also like to have access to the generated [Bindable] code and see what I could come up with, you should inspire the team to make some api for it .
1 person found this helpful
I know you're asking about performance of non-Flex tweening engines, but I'll answer from my Flex 4 effects perspective, since that's what I know. All of the tweening engines, including Flex 4 effects, use a similar approach, however; they just animate the properties of Flex objects. So they would all share similar performance characteristics in general.
The performance of the animations is highly dependent on what's happening in your application. I'm surprised you're seeing as little as 2-4 frames per second, but I would bet there's a lot happening in your app at that time, because it's not hard to achieve much higher frame rates (like 30-60 fps) in very simple situations.
Data binding and layout could be contributing to the performance. I'm not sure how much data binding itself adds (just sending out the events when properties change), but it may be what the listeners are doing with that information that is bogging it down. That is, maybe sending out the event for alpha changing doesn't cost that much, but the listeners may be doing some processing on that change, or any change in general, that is coming at a cost to the system.
There is no flag to disable binding events that I know of. There is a property on Flex effects that disables some event processing (suspendBackgroundProcessing), but it's a bit of a heavy hammer and I wouldn't recommend it as a general approach. (In fact, I'd like to ditch that property since it has some odd consequences at times).
Layout will also contribute to the problem, depending on what's happening. For example, if you are resizing a button in a vertical layout, then the layout will want to shift around the sibling objects to adjust to the size change. That is probably what you want to happen in the UI, but it comes at a cost since the layout has to recalculate everything for the container on every animation update.
There is a flag in Flex effects to reduce the processing of layout in particular: disableLayout=true. This tells Flex to avoid doing layout on the target object's container during the course of the effect. Again, it's a heavy tool to wield, but can be the right thing to do in some situations.
There might be a better general approach we could look into eventually, such as running animations that are more visual than functional (e.g., resizing a button's graphical assets without sending out events as the button changes), but that'll have to come after this release, in which we were focusing on getting the architecture right for spark and flex 4 effects.
In the meantime, I'd play with a profiler and see where you're getting bogged down with your animations; I've seen some pretty slick stuff in non-trival UIs, so the fact that you're seeing such low frame rates means there might be something going on in your app that you could fix rather than waiting for us to think about how to lighten the load for animations.
For example, if you're seeing poor performance for doing a cross-fade between one screen and another, fading out all of the current components and fading in the new components, consider fading alpha on just the container itself. Or using the new CrossFade effect. Once you know more about where your performance issues are coming from, it's easier to figure out how to fix or workaround them in your application.
Just to add to Chet's comments, I've been playing a little with animating multiple complex components and even though layout runs and events are dispatched I haven't experienced that bad of a performance. If you can create a small sample app that reproduces the problem please go ahead and log a bug for us to investigate. Adding additional information like the machine specs will also help.
Thanks guys for all your help, this is great.
I'll create a sample app in a few days when I get some time.
If I run it on my Macbook (10.5.7, safari, 2GB RAM, 1.83 GHz Intel Core Duo), it runs fine. If I run it on a Vista, it's super choppy (don't know the specs of the top of my head), and on an older Mac (10.4.11, safari, 1.5 GHz PowerPC G4, 1.25GM RAM) it's way choppy.