Adobe has made their Flash Player version 10.1 available for some time now. Among some more or less nifty features, they also have a new way of preserving CPU and resources when an application is out of view (different tab or minimized), the application is throttled to a meager 2 frames per second instead of about 60 frames per second.

The throttling effects everything in the application, Timers, Events, LocalConnections etc. The behavior is explained very well in Tinic Uro’s blog post.

I think I understand the rationale here. Currently, an application is running full speed even when it is out of sight from the user. This means that flash applications running on background tabs might eat up CPU without any real reason for it. Since Flash has been taking a lot of flak for this lately I can see how they are eager on improving this. The general idea behind this is sound.

However, my problem with this (and other companies as well)  is that you are breaking backwards compatibility. The throttling affects all timers and event handling. Any type of Flash application that uses multiple windows might use LocalConnection to communicate between the windows/applications. After all, that’s what it’s there for. If any of the participating applications are minimized or hidden, they will almost stop producing/consuming since they are throttled down to 2 FPS.

What is even worse is that you get no notification when this occurs. There are no callbacks or events triggered. Suddenly your application might be running at a 30th of the default speed and you will not be told about this. There is currently no option to avoid being throttled either. To me this is not acceptable if I am developing RIA:s. Imagine writing a desktop application in C++ where your timers suddenly could jump down from 60 FPS to 2 FPS. Without a callback. How would that go with the developer community?

Can this be fixed?

I think so. If Adobe only adds an opt out option for an application I think it would be fine. The default behavior could still be the throttled solution, which would probably work in 90+% of the Flash applications out there. For the freaks like us that are relying on a stable timer and LocalConnection we could explicitly say that we want full FPS even when hidden.

The argument that this could be abused is moot in my opinion. This is the current behavior so you are not making something worse even if everyone decides to opt out from throttling. Besides, what would be the motives for people to ‘abuse’ this behavior? Some evil scheme to waste CPU cycles on people’s computers?

But until then?

If you application is running into problems because of the throttling, there are some things you can try to make things better.

1. Loop a silent MP3 in your applications. Yes, I am serious. This will ramp up the FPS from 2 to 8. Still not much, but four times faster.

2. For LocalConnections you can run a separate LocalConnections per client (if applicable). This will allow you to send more data per tick. *

3. Batch data over LocalConnections. Aggregate as much as you can between ticks and then send it as an Array. Pack it up on the other side.

4. Set the parameter ‘wmode’ to ‘opaque’. This will in theory stop the timer from getting clocked down. Seems to be working for some, but it may depend on your use-case.

Remember that when your ticks go down you need to try and perform as much work as possible for each tick. Of course, this is a bit against the design principles for an asynchronous framework, but hey, that’s what happens when you start to nerf the framerate.

* Edit: This does not seem to be possible. The routing seems to be executed outside the LocalConnection, meaning that all events sent will be dispatched sequentially in a throttled manner to all recipients. Ergo, if you have one broker and four clients (think online poker game with one lobby and four tables) then for the 2 FPS case each client will receive a maximum of 1 event every two seconds. Yikes.

Fredrik Johansson is a founder and CEO of Cubeia Ltd.

You can contact him at: fredrik.johansson(at)