I love Adobe AIR! I think it’s an amazing platform with a huge amount of potential. However, AIR has one problem that could earn it a bad reputation before it has a chance to truly realize that potential – idle CPU usage.
Try this on a Mac: open FlashCS4. Create a new, completely empty FLA and publish it as an AIR file. Install it, run it, and examine it in Activity Monitor. On my brand new MacBook Pro, that completely empty AIR application uses nearly 4% of my CPU. Doing nothing. In the background.
Now look at the types of applications that are popular on AIR: Twitter apps, news apps, notification apps, mashups. Applications that are designed to be left open all the time. Open a few of these up at once, and you’re committing a decent chunk of your CPU to them. And that’s when they’re doing nothing. I typically have 10-20 applications open at all times. If these were all AIR applications, half of my CPU would be used just from having them open.
Expected CPU use for an idle application doing nothing is ~0%. An acceptable level is <1%. AIR must fit into this range cross-platform to be a serious contender on the desktop. This issue does not affect Windows. I haven't tested on Linux yet. It's also worth noting that this problem isn't limited to AIR, it appears to be an issue with the player itself. Try the same test with an empty SWF running in the standalone player or the browser, and you'll notice the same kind of CPU usage. I believe this may be part of the reason that FlashCS4 on the Mac eats so much idle CPU - it has at least 2 instances of the Flash player running in it, one for stage core, and one for panels. I've been in contact with the team at Adobe, and they have acknowledged that they are aware of the issue, and are actively working to address it. Despite that, I felt it would still be good to write this post for three reasons: The first reason is to create awareness of this issue, and hopefully through that awareness help to generate some external pressure on Adobe to fix the problem in a timely manner. If you feel this issue is important to you, spread the word about it, and please vote up bug #FP-2009 in the Flash Player bug system. To do so, register on Adobe’s JIRA bug system, do a quick search for “FP-2009”, and vote for the issue using the link in the left column.
The second reason is that I’ve had to explain this issue to our clients a few times recently, and I thought it would be useful for other developers to have a post explaining and validating the issue so they could refer their own clients to it.
Finally, I thought it would be good to provide a location where developers can share tips on working around this issue until Adobe addresses it. As a start to that, I have created a simple class that will automatically reduce your application’s frame rate when it is in the background, and restore it when it regains focus. You can also temporarily restore the framerate while in the background (for example, if you loaded some new data and wanted to transition it in smoothly). Reducing the framerate is the best method I’ve found so far for improving idle performance. Using the class is simple:
// this should be called as soon as your application starts up and has an open window. // the first parameter is optional, and specifies the background fps to use (default is 1) FramerateThrottler.initialize(2); // set enabled to false to temporarily restore the framerate while in the background, or prevent it from reducing the framerate // when your application moves to the background: FramerateThrottler.enabled = false; // you can also specify whether to only use this feature when running on a Mac: FramerateThrottler.onlyThrottleOnMac = true; |
You can download the FramerateThrottler class here.
Update:
Robert Christensen, Sr. Product Manager for Adobe AIR has posted an entry on the AIR Team Blog addressing my concerns titled “Performance Tips for Adobe AIR. I think its awesome how responsive Adobe is to issues like these! Thanks Rob!
Arno Gourdol, Sr. Engineering Manager on the Adobe AIR team just posted a blog entry on “Writing well-behaved, efficient, AIR applications“. The suggestions break down to reducing your framerate (see above), and minimizing the use of Timers and enterFrame listeners. Worth a read.
Update 2:
As a real world example, we added FramerateThrottler to an AIR application we are currently working on. It was originally using 5-10% CPU idling in the background, with FramerateThrottler it’s now using 0.5%. We also tried setting mouseEnabled and mouseChildren to false on the stage of all open windows while in the background, but that had minimal effect, dropping it to ~0.4%.
Thanks for the FYI. voted
Awesome stuff. I’m doing a lot of new work in AIR and was curious how it handles on other OSes.
Consider that bug voted/watched.
Good point, Grant. +1 vote from here.
Hi Grant,
Thank you for sharing your concerns. As we have talked about in person, reducing the CPU usage on Mac is one of the areas that we are making investments in the next versions of Adobe AIR and Flash Player. We are laser-focused on improving CPU usage and recognize that it is a concern other developers and end users share as well. We hear you and we are absolutely positively working on it. 🙂
I am working on a blog post on our team blog to share a few tips related to this topic.
Thank you,
-Rob
Product Manager, Adobe AIR
Good to know, thanks for the info Grant. Up-voted on the bugs database – here’s the direct link: https://bugs.adobe.com/jira/browse/FP-2009
Thank you for the info gskinner.
Really cool Grant!
This will only work with apps that only launches one window.
Also, you are not using weak references for listeners. Smth i learnt from you 🙂
Cheers!
Fernando – this should work for apps with any number of windows. Framerate is shared between all windows in an AIR app, so you only need to set it on one.
I didn’t use weakly referenced listeners because this is a persistent static class, so it isn’t an issue. It would be good practice to do so anyway, just to keep it as a habit. 😉
hey cool, is this class just for air, or can I use it in the browser too?
Per my earlier comment, I posted a reply on our blog post as well along with a few tips.
http://blogs.adobe.com/air/2009/05/performance_tips_for_adobe_air.html
Thanks,
Rob Christensen
Adobe AIR Team
Thanks Grant! Will vote.
Duane
PS: Go Canucks!!!
Thanks for the info Grant. I am curious what kind of performance you have seen with html based Air apps. I am wondering if the performance issues are on the Flash Player or the AIR runtime.
i don’t know why but adobe was always bad on mac
1. flash player installation: on mac you have to restart your browser (even with express install). on windows you dont have to. but unity3d can install its player without restarting on mac. why not adobe?
2. mousewheel-support: possible on windows. not working on mac. some guy has to build his own solution. he can. why not adobe?
3. font kerning: possible on windows. not working on mac. why?
4. performance: was and still is better on windows. why?
you’re so right peter!
i am asking me the same questions again and again.
Apple and Flash do not play well together. The performance of Flash video in Safari 3 on Mac is atrocious. I use Firefox almost exclusively because of this. Hopefully Adobe and Apple will work out whatever differences they have that underlie this and the lack of Flash on iPhone. Both issues, I believe, are hurting both companies.
The cpu usage has also a relation to the number of display objects on stage. if you have a lot of display object and you set mouseEnable to false (if possible) it uses less cpu. there are also some other stange issues with this topic. (mouse over an input textfield set cpu usage to 0%)
for a detailed bug report (FP-1149) have a look at: http://bugs.adobe.com/jira/browse/FP-1149
its also strange that in avm1 (actionscript2) it was much better. i think it is related to the way how operation systems mouse events are handled by the flashplayer.
excerpt from the bug entry:
Test results:
AS3 code (-> AVM2)
AS3: framerate 24:
mouse over the stage: 3%
mouse over the textField: 0%
mouse over the one sprite: 3%
mouse over the stack of 1000 sprites: 3%
AS3: framerate 120:
mouse over the stage: 9-14%
mouse over the textField: 0%
mouse over the one sprite: 10-13%
mouse over the stack of 1000 sprites: 14-18%
AS3: framerate 1000:
mouse over the stage: 36-40%
mouse over the textField: 0%
mouse over the one sprite: 22-40%
mouse over the stack of 1000 sprites: 17-33%
AS2 code (-> AVM1)
AS2: framerate 24:
mouse over the stage: 0%
mouse over the textField: 0%
mouse over the one sprite: 0%
mouse over the stack of 1000 sprites: 0%
AS2: framerate 120:
mouse over the stage: 6%
mouse over the textField: 0%
mouse over the one sprite: 6%
mouse over the stack of 1000 sprites: 6%
AS2: framerate 1000:
mouse over the stage: 8%
mouse over the textField: 0%
mouse over the one sprite: 8%
mouse over the stack of 1000 sprites: 8%
Thanks so much Grant !!
Hi, this is great I work for Tamooz (www.tamooz.net)
we do a lot of desktop apps for conventions before AIR we have been using Zinc, we tried to move to AIR but we came across this issue.
Thanks loads for this Grant!
I’m the developer & designer for the Tweetminster Wire and CPU Usage has been a huge problem. This has solved everything :).
A simple concept and it works great!!
I’ve noticed this usage as well, particularly since my first-gen MacBookPro kicks on the fan even with a relatively light AIR app running. It’s really frustrating, because even Flash itself takes a lot of things going to produce that kind of CPU usage. I wouldn’t be surprised if it’s due to inefficiencies in the Flash player on Mac.
Thanks a bunch, great post!!! Just voted
I work mostly with Flash, not with AIR, but this article has been very useful all the same. However, I have a burning question: is it possible for me to somehow see more detailed CPU usage for what’s going on in the Flash Player? Something similar to what Manfred Karrer posted earlier:
“excerpt from the bug entry:
Test results:
AS3 code (-> AVM2)
AS3: framerate 24:
mouse over the stage: 3%
mouse over the textField: 0%
mouse over the one sprite: 3%
mouse over the stack of 1000 sprites: 3%”
Thank you!
There was a very similar problem in Director i remember having implemented a multipart solution to manage the problem.
There was also a very special trick that i could not have figured out myself and found on the web, it was something like:
On Idle
sleep 1
end
That was making the application idle cpu usage dropping very effectively!
Untested but . . . seems like you can accomplish the same thing on the Web with a simple time-out script that throttles the fps after XX amount of time has passed with no Mouse activity. Resets the fps the instant the mouse moves. Or, I suppose, catch window focus/blur with JavaScript and ExternalInterface, but why complicate matters?
Grant,
When you say that “it appears to be an issue with the player itself,” do you mean Flash Player 10 as a whole or the specific version of the player that is part of Flash CS4 (which I believe is the same thing)?
Please post a response when you can and thanks for the heads up. We get a good handful of CPU-related issues in the ad serving world.
Todd
Hey Grant,
I tested the class and it’s working great.
The only issue is, that if you have an item that is animated when you mouse over it and having the framerate throttled, the framerate should get back to normal since the transition doesn’t look good with 1FPS only.
What would you suggest?
hey Grant,
thanks for the post and +1 from me.
is it really true that AIR stages in separate NativeWindows share a framerate?
also out of curiousity is this integrated into the latest version of combined gTween/TweenLite?
..I am using a modified TweenLite and not sure if I should update my code 😉
Thanks again,
Lushen
I did a quick test and confirmed they share framerates… never would have guessed!
why is it that flash player has such poor performance on mac?
With the latest version of flashplayer 10, Youtube videos are unwatchable on my iMac G5 (1.8 GHz). they play at about 5fps and even the audio skips, all the while maxing out the cpu.
even basic flash ads on websites result in 70% plus cpu usage.
I tried this in firefox 2, 3 Safari 3, camino and opera browsers. there was no noticeable difference in performance or cpu usage.
viewing the same pages on a 1.8 ghz pentium M laptop running windows xp sp3: (also fp 10) the youtube clips played smoothly with 20-30% cpu usage while the same flash ads only used 5=10 % cpu.
I have now gone back to flash 9 on the mac as youtube videos at least work with it.
I’m having a slight problem with your framerateThrottler. When I go idle, it drops the framerate as expected. However, when I return back to the app, it sets the framerate to 24fps, even though I’ve specified 5fps in the initialise method (which is tracing correctly). I’ve checked through the code and it all seems ok, so I’m a little confused as to why this would be happening 🙁
The FramerateThrottler class is awesome, thx for sharing!
Question for method “throttleFramerate”: Why did you store _activeFramerate again using a framerate of an opened window (line 137)? It seems that enabling / disabling FramerateThrottler again and again an opened window have sometimes a frame rate of 1 ( _backgroundFramerate) at this moment. So it’s not possible to switch back to “normal” framerate. Maybe an issue on a Mac only. Commenting out the line “_activeFramerate = na.openedWindows[0].stage.frameRate;” fixed this issue.
Anyway, great stuff – thanks again!
-Jens
Skype is the worst offender ~12% (again no problem on Windows)
I also find it interesting that our AIR app actually uses more cpu when hidden and idle (4%) compared to visiblie (as far as Finder is concerned) and idle.. 2%
Skype, however, although worst offender in visible state, does drop to about 3.5% in when hidden.
Thanks for the tips, will be trying out the throttler soon.
I am developing a combined Adobe Flex and AIR application to manage and organize knowledge, based on topic maps: http://www.quesucede.com/page/show/id/polishedcode. Furthermore, the actual topic map engine was developed with ActionScript 3 and uses SQLite as a backing store (for object graph serialization and de-serialization).
Grant,
Per JIRA, the issue is fixed but there’s no info as to where and how it was fixed. Do you have any data?
Jeff
it might be worth noting that if you’re developing your AIR app in flash CS4 you can still use the flex builder profiler via the profile > profile external application option in flex builder …
i trm having a slight problem with your framerateThrottler. When I go idle, it drops the framerate as expected. However, when I return back to the app, it sets the framerate to 24fps, even though I’ve specified 5fps in the initialise method (which is tracing correctly). I’ve checked through the code and it all seems ok, so I’m a little confused as to why this would be happening 🙁
Itâs something we really hope Adobe will take seriously and address in upcoming releases. Until then, as mentioned in the article, the problem can be partly remedied by simply reducing the framerate when idling in the background.
thnk you for sharing
Gosh, what a great post! My Mac slows throughout the day, and I was wondering why – and now I know. Is this still an open issue, because as far as I am concerned this seems to be getting worse/slower than better. Is that because there are more AIR based programs now or is it just that they use more CPU time now when idle?