Wednesday 29 February 2012

Flash isn't slow

Flash has a reputation for being slow, but one I think that is largely undeserved. It is not as fast as native code but is not that far behind, and compares favourably with other interpreted cross-platform environments.


But why does it have a reputation for poor performance? I think there are a number of reasons, all of which are pitfalls developers can fall into when making Flash games. Avoid these and it becomes much easier to make games which perform well across a wide range of platforms. So what are these pitfalls?


Poor Tools: The Flash compiler in particular does a very poor job of optimising ActionScript code. It's integrated closely into the Flash IDE though, so can't easily be replaced with another, on the command line for example. The Flex compiler is command line but requires projects to be set up in a completely different way.


This requires a lot of unlearning when moving from e.g. C++ to Flash, as you have to do the work of optimising yourself. Or drop ActionScript and use an entirely different language such as haxe.


High level assets: Flash comes with a number of high level classes which seem ideal for game objects, such as MovieClips, SimpleButtons, various components and controls. These are fine if used singly but too slow for game assets because their extra overhead means they rapidly bog down a game if overused.


The best approach is to use low level assets, especially Bitmap and BitmapData objects, with events and animation handled in optimised, centralised code, not run on every object. Leave MovieClips to artists making websites in Flash CS.


Events: Flash events are slow if overused. It's tempting to add event listeners to every object, or to use Timer events to trigger events, as both seem designed for this. But too many events slow the game down, as well as rendering it unpredictable as the order in which events fire can vary greatly.


Timer events are not needed at all in a game: everything can be run off the main ENTER_FRAME event (which there should be only one of). If precise timing is needed then the millisecond timer getTimer() can be used. Similarly there should be only one MouseEvent for the whole game, with code used to decide what is clicked at any time.


ActionScript 2: There are still a lot of games made with ActionScript 2 which makes no sense. It's slow and getting relatively slower every Flash release as Adobe improve AVM2 (the runtime for ActionScript 3).


This makes no sense to me as ActionScript 3 has been out for years, uses the same tools as ActionScript 2, and is very close in terms of the APIs and design. Anyone using ActionScript 2 should have switched by now, to do all they are doing with ActionScript 2 and much more.


Testing: This is somethings I maybe notice more because of my computer, a five year old Mac with a slow graphics card. I can't run many modern games, but surprisingly I also can't run quite a few Flash games. Whoever made them did not think of testing on older computers, or with other OSes.


This is not something limited to older PCs but even a modern PC can struggle to play a game if the game is demanding and the computer is running slowly for other reasons. Users quite reasonably don't expect Flash games to use 50-100% of a dual core CPU, and won't necessarily quit their background apps or close other windows to give an expensive game more resources.

2 comments:

  1. Good post. You mention high level assets; what would you consider the Sprite? I'd like to work with the Bitmap more, but find Sprite so damned convenient.

    ReplyDelete
  2. Sprites are half way between Bitmap and MovieClip classes. Their problem for performance is they are both containers and interactive objects. Being containers they are more work for the garbage collector if it has to clean a lot of them up. Being interactive objects they respond to many events.

    It's the latter that I've noticed as a performance problem: if you have a lot of Sprites (or MovieClips, or SimpleButtons) it can mean mouse clicks take a lot time to process as everything under the mouse is checked. You can disable this but I find it better to use Bitmaps and occasional Graphics commands, then have one mouse handler on the stage that catches all clicks and passes them to whatever's clicked on (as the game knows where everything is).

    ReplyDelete