This page is an ongoing attempt to bring order to the chaos that is our collective knowledge on ActionScript optimisation, and to a lesser degree, its closely related topic of memory management.
I’ve ordered the optimisation by type, allowing you to be selective about what you read.
If you have any comments, post them here.
Disclaimer: I do not by any means claim that all of these tips are 100% true 100% of the time. There are a few I am uncertain about, which I’ve marked accordingly. Common sense says you should pick your tools wisely, and know the implications thereof. This is simply a compilation of mine and others’ optimisation experiences and, to the authors, I apologise if any of these tips have been misinterpreted in terms of context. If nothing else, this document will give you a sense of what is “okay” and “not okay” whenit comes to optimising ActionScript.
Please see the star-spangled list of authors who made this comprehensive list possible by sharing their own optimisation tips, at the end of this document.
Happy optimising!
Category: Control Structures
- Do not instantiate an object within a loop when instantiating it outside would do just as well. (AS2, AS3)
- try..catch can be orders of magnitude slower than a simple if..else (AS2?, AS3)
- Reading arrays: for..in tends to be faster than while and for (AS2?, AS3)
- Writing arrays: while is faster than for (AS2?, AS3)
- Do not use array.length inside loops or loop headers. Either use for..in instead, or assign array.length to a local variable prior to entering the loop. (AS2, AS3)
- Avoid calling a function multiple times from within a loop. It is better to include the contents of a small function inside the loop. (AS2, AS3)
- Use nested if statements rather than combined if conditions. (AS2?, AS3?)
- Within loop counters, uint/int is faster than Number (AS3)
Category: Variables, Types & References
- Make use of strict typing: Declare the types of all variables, and use the var keyword whenever you declare in local scope. (AS2, AS3)
- Use very short variable names (1-3 letters if possible) (AS2, AS3)
- Use lazy/deferred/JIT instantiation (AS2, AS3)
- For array lookups, uint/int is faster than Number (AS3)
- Access objects’ data members directly, i.e without using get and set methods (AS2, AS3)
- Don’t use multidimensional arrays. Build your own (optimised) multidimensional list class instead. (AS2, AS3)
- Don’t use static or global variables when instance variables will suffice. (AS2, AS3)
- Don’t use data members (instance variables) when local variables will suffice. (AS2, AS3)
- Use constants instead of variables where appropriate. (AS2, AS3)
- Use single line variable declarations/initialisations where possible, eg. var i:int, j:int, k:int = 10; (AS2?, AS3)
- Always typecast objects taken from arrays before using their methods, as array elements have no defined type (otherwise AS’s native dynamic typing will slow down your code). The as keyword may be used for this. (AS2, AS3)
- Use native functions when possible. Native functions are faster than user-defined functions. (AS2?, AS3?) (Note: I am seriously skeptical about this one.)
- Accessing object properties: with is faster than dot syntax is faster than this. (AS2, AS3?) (Note: Using with under AS3 is bad news, am I alone here?)
Category: Math
- Pre-define your formulae in as much as possible, and assign the results to consts, particularly intensive functions such as those using trigonometry. (AS2, AS3)
- Use Number for math operations. There are cases where int is faster but it is generally best to stick with Number. (Note: I believe this is referring to all cases where the result may be floating point, i.e. only use int when doing subtractions, additions and multiplications of whole numbers, or divisions where the result is guaranteed to be a whole number, because in these cases using int requires an implicit typecast if it is a self-assignment operation such as *=.) (AS3)
- Be sure to recast to int for array access and loops. Just because you did
int a;…doesn’t mean that a is still an int. It will now have become a Number.
a *= 2; - Use multiplication instead of division. (AS2, AS3)
- Use bitwise operators for arithmetic. (AS2, AS3)
Category: Display
- Use BitmapData to create a single drawing canvas and draw bitmaps onto it, rather than using the usual collections of DisplayObjects using bitmaps or vectors. (AS2, AS3) (Note: Is this also faster than using the drawing API, or are they one and the same?)
- To hide an object on the stage, remove it from the Display List with removeChild(). Unlike AS2, It will continue to exist until such time as you wish to redisplay it, so long as there is another object with a reference to it. (AS3)
- To hide an object on the stage, set its _visible property to false rather than setting its _alpha (AS2) property to zero.
- Don’t use alpha PNGs if at all possible. They require software based alpha calculations, which are very processor intensive. (AS2, AS3)
- Don’t use masks if at all possible. Shape clipping using masks is very processor intensive. (AS2, AS3)
- Use TellTarget instead of MovieClip dot syntax to change MovieClip properties. (AS2, AS3?)
- Use cacheAsBitmap on DisplayObjects for all your expected rotated/transformed frames, and save the results into an array. NB: If you use cacheAsBitmap on something that is going to undergo other (AS2, AS3) (Note: I may have reworded this incorrectly, this is how I understand it; comments welcome.) transforms anyway, you will lose performance rather than gain it, as it must cache each frame as well as rendering).
- Use onEnterFrame as sparingly as possible (not at all, if you can help it). If you use it, remember to set onEnterFrame = null and to delete onEnterFrame (AS2, AS3)
- ASBroadcaster is faster than loops for cycling through MCs. (AS2)
Category: Generic Best Practices
- Remove listeners and object references as soon as they are no longer needed. (AS2, AS3)
- Remove trace() statements for performance testing and release builds. (AS2, AS3)
- Keep arrays (and for that matter any other collection-type data structures) densely packed. (AS2, AS3)
- Don’t misuse/overuse the native Object type. Data-type annotations should be precise, as it improves performance. Create a suitable new class whenever possible, rather than using Object and extending it’s members and methods. Custom classes are sealed by default in AS3 for good reason. (AS2, AS3) (Note: This is likely to actually be the larger issue of avoiding the use of dynamic objects.)
- Avoid using eval() or the array access operator [ ] if possible. Set a local reference once, instead. (AS2, AS3)
- Assign commonly referenced methods and properties of an object to local consts and vars to in order to minimize object references, e.g. const PI:Number = Number(Math.PI), const RUN:Function = sprite.Run(), etc. (Other side of the coin) “Storing package functions as constants such as const abs:Function = Math.abs resulted in run times 70-75 percent slower.” (AS2, AS3) (Note: I am sure this because Math is static, your comments, si vous plez?)
- If speed is more important than simple and reliable garbage collection, do not use weak references with EventListener and Dictionary instances. Otherwise, always use weak references for the GC reliability they provide. (AS3)
- Not all code needs to run on every frame. Do not abuse onEnterFrame: the frame rate is intended for display, not necessarily logic. (AS2, AS3)
- If using setInterval(), be sure to clear it with clearInterval() once the tick is not longer need. (AS2, AS3)
- Use object pools to reuse frequently created/destroyed class instances. (AS2, AS3)
Category: Compiler and Flash Player Options
- Set compiler option optimize=true (this is the default, but be sure to check). (AS2?, AS3)
Category: Introspection
- Avoid getDefinitionByName(getQualifiedClassName(object)); create your own custom reflection methods instead if possible. (AS3)
Sources
Many thanks to the following authors. I’ve tried to give article-specific URLs where necessary but some authors’ sites are just littered with optimization stuff (which is a good thing).
Ryan Kettrey - http://blog.poweredbyhamsters.com/2007/10/01/optimizing-actionscript-3.aspx
Marco Lapi - http://www.gotoandplay.it/_articles/2004/01/as_optimizations_p02.php
Jeff Fulton - http://www.8bitrocket.com/newsdisplay.aspx?newspage=7496
Mike Baczynski - http://lab.polygonal.de/
Daniel Hai - http://www.danielhai.com/blog/?p=55
Grant Skinner - http://www.adobe.com/devnet/flashplayer/articles/resource_management.html
Dennis Ippel - http://rozengain.com/?postid=35
Jody Brewster - http://blog.jodybrewster.net/2008/04/26/actionscript-30-optimization-techniques/
Adobe LiveDocs - http://www.adobe.com/devnet/flash/articles/as_bestpractices_02.html
Additional Sources
Other sources I’ve found since my last revision of this page:
OSFlash.org also has a unified optimisations page: http://osflash.org/as3_speed_optimizations
Fast integer math using bitwise ops: http://lab.polygonal.de/2007/05/10/bitwise-gems-fast-integer-math/
Superfast way to copy an array: http://agit8.turbulent.ca/bwp/2008/08/04/flash-as3-optimization-fastest-way-to-copy-an-array/