. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .921Last updated 9/28/2011Chapter 1: IntroductionAdobe® AIR® and Adobe® Flash® Player applications run on many platforms, including desktops, mobile devices,tablets, and television devices. Through code examples and use cases, this document outlines best practices fordevelopers deploying these applications. Topics include:•Conserving memory•Minimizing CPU usage•Improving ActionScript 3.0 performance•Increasing rendering speed•Optimizing network interaction•Working with audio and video•Optimizing SQL database performance•Benchmarking and deploying applicationsMost of these optimizations apply to applications on all devices, on both the AIR runtime and Flash Player runtime.Additions and exceptions for specific devices are also discussed.Some of these optimizations focus on capabilities introduced in Flash Player 10.1 and AIR 2.5. However, many of theseoptimizations apply to earlier AIR and Flash Player releases, too.Runtime code execution fundamentalsOne key to understanding how to improve application performance is to understand how the Flash Platform runtimeexecutes code. The runtime operates in a loop with certain actions occurring each “frame.” A frame in this case issimply a block of time determined by the frame rate specified for the application. The amount of time allotted to eachframe directly corresponds to the frame rate. For example, if you specify a frame rate of 30 frames per second, theruntime attempts to make each frame last one-thirtieth of a second.You specify the initial frame rate for your application at authoring time. You can set the frame rate using settings inAdobe® Flash® Builder™ or Flash Professional. You can also specify the initial frame rate in code. Set the frame rate inan ActionScript-only application by applying the[SWF(frameRate="24")]metadata tag to your root document class.In MXML, set theframeRateattribute in the Application or WindowedApplication tag.Each frame loop consists of two phases, divided into three parts: events, theenterFrameevent, and rendering.The first phase includes two parts (events and theenterFrameevent), both of which potentially result in your codebeing called. In the first part of the first phase, runtime events arrive and are dispatched. These events can representcompletion or progress of asynchronous operations, such as a response from loading data over a network. They alsoinclude events from user input. As events are dispatched, the runtime executes your code in listeners you’ve registered.If no events occur, the runtime waits to complete this execution phase without performing any action. The runtimenever speeds up the frame rate due to lack of activity. If events occur during other parts of the execution cycle, theruntime queues up those events and dispatches them in the next frame.The second part of the first phase is theenterFrameevent. This event is distinct from the others because it is alwaysdispatched once per frame.2OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMIntroductionLast updated 9/28/2011Once all the events are dispatched, the rendering phase of the frame loop begins. At that point the runtime calculatesthe state of all visible elements on the screen and draws them to the screen. Then the process repeats itself, like a runnergoing around a racetrack.Note: For events that include anupdateAfterEventproperty, rendering can be forced to occur immediately instead ofwaiting for the rendering phase. However, avoid usingupdateAfterEventif it frequently leads to performanceproblems.It's easiest to imagine that the two phases in the frame loop take equal amounts of time. In that case, during half of eachframe loop event handlers and application code are running, and during the other half, rendering occurs. However,the reality is often different. Sometimes application code takes more than half the available time in the frame,stretching its time allotment, and reducing the allotment available for rendering. In other cases, especially withcomplex visual content such as filters and blend modes, the rendering requires more than half the frame time. Becausethe actual time taken by the phases is flexible, the frame loop is commonly known as the “elastic racetrack.”If the combined operations of the frame loop (code execution and rendering) take too long, the runtime isn’t able tomaintain the frame rate. The frame expands, taking longer than its allotted time, so there is a delay before the nextframe is triggered. For example, if a frame loop takes longer than one-thirtieth of a second, the runtime is not able toupdate the screen at 30 frames per second. When the frame rate slows, the experience degrades. At best animationbecomes choppy. In worse cases, the application freezes and the window goes blank.For more details about the Flash Platform runtime code execution and rendering model, see the following resources:•Flash Player Mental Model - The Elastic Racetrack(article by Ted Patrick)•Asynchronous ActionScript Execution(article by Trevor McCauley)•Optimizing Adobe AIR for code execution, memory & rendering athttp://www.adobe.com/go/learn_fp_air_perf_tv_en(Video of MAX conference presentation by Sean Christmann)Perceived performance versus actual performanceThe ultimate judges of whether your application performs well are the application’s users. Developers can measureapplication performance in terms of how much time certain operations take to run, or how many instances of objectsare created. However, those metrics aren’t important to end users. Sometimes users measure performance by differentcriteria. For example, does the application operate quickly and smoothly, and respond quickly to input? Does it havea negative affect on the performance of the system? Ask yourself the following questions, which are tests of perceivedperformance:•Are animations smooth or choppy?•Does video content look smooth or choppy?•Do audio clips play continuously, or do they pause and resume?•Does the window flicker or turn blank during long operations?•When you type, does the text input keep up or lag behind?•If you click, does something happen immediately, or is there a delay?•Does the CPU fan get louder when the application runs?•On a laptop computer or mobile device, does the battery deplete quickly while running the application?•Do other applications respond poorly when the application is running?3OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMIntroductionLast updated 9/28/2011The distinction between perceived performance and actual performance is important. The way to achieve the bestperceived performance isn’t always the same as the way to get the absolute fastest performance. Make sure that yourapplication never executes so much code that the runtime isn’t able to frequently update the screen and gather userinput. In some cases, achieving this balance involves dividing up a program task into parts so that, between parts, theruntime updates the screen. (See“Rendering performance” on page

45for specific guidance.)The tips and techniques described here target improvements in both actual code execution performance and in howusers perceive performance.Target your optimizationsSome performance improvements do not create a noticeable improvement for users. It’s important to concentrateyour performance optimizations on areas that are problems for your specific application. Some performanceoptimizations are general good practices and can always be followed. For other optimizations, whether they are usefuldepends on your application’s needs and its anticipated user base. For example, applications always perform better ifyou don’t use any animation, video, or graphic filters and effects. However, one of the reasons for using the FlashPlatform to build applications is because of the media and graphics capabilities that allow rich expressive applications.Consider whether your desired level of richness is a good match for the performance characteristics of the machinesand devices on which your application runs.One common piece of advice is to “avoid optimizing too early.” Some performance optimizations require writing codein a way that is harder to read or less flexible. Such code, once optimized, is more difficult to maintain. For theseoptimizations, it is often better to wait and determine whether a particular section of code performs poorly beforechoosing to optimize the code.Improving performance sometimes involves making trade-offs. Ideally, reducing the amount of memory consumedby an application also increases the speed at which the application performs a task. However, that type of idealimprovement isn’t always possible. For example, if an application freezes during an operation, the solution ofteninvolves dividing up work to run over multiple frames. Because the work is being divided up, it is likely to take longeroverall to accomplish the process. However, it is possible for the user to not notice the additional time, if theapplication continues to respond to input and doesn’t freeze.One key to knowing what to optimize, and whether optimizations are helpful, is to conduct performance tests. Severaltechniques and tips for testing performance are described in“Benchmarking and deploying” on page

91.For more information about determining parts of an application that are good candidates for optimization, see thefollowing resources:•Performance-tuning apps for AIR athttp://www.adobe.com/go/learn_fp_goldman_tv_en(Video of MAXconference presentation by Oliver Goldman)•Performance-tuning Adobe AIR applications athttp://www.adobe.com/go/learn_fp_air_perf_devnet_en(AdobeDeveloper Connection article by Oliver Goldman, based on the presentation)4Last updated 9/28/2011Chapter 2: Conserving memoryConserving memory is always important in application development, even for desktop applications. Mobile devices,however, place a premium on memory consumption, and it is worthwhile to limit the amount of memory yourapplication consumes.Display objectsChoose an appropriate display object.

ActionScript 3.0 includes a large set of display objects. One of the most simple optimization tips to limit memory usageis to use the appropriate type of display object. For simple shapes that are not interactive, use Shape objects. Forinteractive objects that don’t need a timeline, use Sprite objects. For animation that uses a timeline, use MovieClipobjects. Always choose the most efficient type of object for your application.The following code shows memory usage for different display objects:

trace(getSize(new Shape()));

// output: 236

trace(getSize(new Sprite()));

// output: 412

trace(getSize(new MovieClip()));

// output: 440ThegetSize()method shows how many bytes an object consumes in memory. You can see that using multipleMovieClip objects instead of simple Shape objects can waste memory if the capabilities of a MovieClip object are notneeded.Primitive typesUse thegetSize()method to benchmark code and determine the most efficient object for the task.

All primitive types except String use 4 – 8 bytes in memory. There is no way to optimize memory by using a specifictype for a primitive:5OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011

// Primitive types

var a:Number;

trace(getSize(a));

// output: 8

var b:int;

trace(getSize(b));

// output: 4

var c:uint;

trace(getSize(c));

// output: 4

var d:Boolean;

trace(getSize(d));

// output: 4

var e:String;

trace(getSize(e));

// output: 4A Number, which represents a 64-bit value, is allocated 8 bytes by the ActionScript Virtual Machine (AVM), if it is notassigned a value. All other primitive types are stored in 4 bytes.

// Primitive types

var a:Number = 8;

trace(getSize(a));

// output: 4

a = Number.MAX_VALUE;

trace(getSize(a));

// output: 8The behavior differs for the String type. The amount of storage allocated is based on the length of the String:

var name:String;

trace(getSize(name));

// output: 4

name = "";

trace(getSize(name));

// output: 24

name = "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsumhas been the industry's standard dummy text ever since the 1500s, when an unknown printer tooka galley of type and scrambled it to make a type specimen book. It has survived not only fivecenturies, but also the leap into electronic typesetting, remaining essentially unchanged. Itwas popularized in the 1960s with the release of Letraset sheets containing Lorem Ipsumpassages, and more recently with desktop publishing software like Aldus PageMaker includingversions of Lorem Ipsum.";

trace(getSize(name));

// output: 1172Use thegetSize()method to benchmark code and determine the most efficient object for the task.6OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011Reusing objectsReuse objects, when possible, instead of recreating them.

Another simple way to optimize memory is to reuse objects and avoid recreating them whenever possible. Forexample, in a loop, do not use the following code:

const MAX_NUM:int = 18;

const COLOR:uint = 0xCCCCCC;

var area:Rectangle;

for (var:int = 0; i < MAX_NUM; i++)

{

// Do not use the following code

area = new Rectangle(i,0,1,10);

myBitmapData.fillRect(area,COLOR);

}Recreating the Rectangle object in each loop iteration uses more memory and is slower because a new object is createdin each iteration. Use the following approach:

const MAX_NUM:int = 18;

const COLOR:uint = 0xCCCCCC;

// Create the rectangle outside the loop

var area:Rectangle = new Rectangle(0,0,1,10);

for (var:int = 0; i < MAX_NUM; i++)

{

area.x = i;

myBitmapData.fillRect(area,COLOR);

}The previous example used an object with a relatively small memory impact. The next example demonstrates largermemory savings by reusing a BitmapData object. The following code to create a tiling effect wastes memory:var myImage:BitmapData;

var myContainer:Bitmap;

const MAX_NUM:int = 300;

for (var i:int = 0; i< MAX_NUM; i++)

{

// Create a 20 x 20 pixel bitmap, non-transparent

myImage = new BitmapData(20,20,false,0xF0D062);

// Create a container for each BitmapData instance

myContainer = new Bitmap(myImage);

// Add it to the display list

addChild(myContainer);

// Place each container

myContainer.x = (myContainer.width + 8) * Math.round(i % 20);

myContainer.y = (myContainer.height + 8) * int(i / 20);

}7OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011Note: When using positive values, casting the rounded value to int is much faster than using theMath.floor()method.The following image shows the result of the bitmap tiling:Result of bitmap tilingAn optimized version creates a single BitmapData instance referenced by multiple Bitmap instances and produces thesame result:

// Create a single 20 x 20 pixel bitmap, non-transparent

var myImage:BitmapData = new BitmapData(20,20,false,0xF0D062);

var myContainer:Bitmap;

const MAX_NUM:int = 300;

for (var i:int = 0; i< MAX_NUM; i++)

{

// Create a container referencing the BitmapData instance

myContainer = new Bitmap(myImage);

// Add it to the display list

addChild(myContainer);

// Place each container

myContainer.x = (myContainer.width + 8) * Math.round(i % 20);

myContainer.y = (myContainer.height + 8) * int(i / 20);

}This approach saves about 700 KB in memory, which is a significant savings on a traditional mobile device. Eachbitmap container can be manipulated without altering the original BitmapData instance by using the Bitmapproperties:8OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011

// Create a single 20 x 20 pixel bitmap, non-transparent

var myImage:BitmapData = new BitmapData(20,20,false,0xF0D062);

var myContainer:Bitmap;

const MAX_NUM:int = 300;

for (var i:int = 0; i< MAX_NUM; i++)

{

// Create a container referencing the BitmapData instance

myContainer = new Bitmap(myImage);

// Add it to the DisplayList

addChild(myContainer);

// Place each container

myContainer.x = (myContainer.width + 8) * Math.round(i % 20);

myContainer.y = (myContainer.height + 8) * int(i / 20);

// Set a specific rotation, alpha, and depth

myContainer.rotation = Math.random()*360;

myContainer.alpha = Math.random();

myContainer.scaleX = myContainer.scaleY = Math.random();

}The following image shows the result of the bitmap transformations:Result of bitmap transformationsMore Help topics“Bitmap caching” on page

Another important optimization is called object pooling, which involves reusing objects over time. You create adefined number of objects during the initialization of your application and store them inside a pool, such as an Arrayor Vector object. Once you are done with an object, you deactivate it so that it does not consume CPU resources, andyou remove all mutual references. However, you do not set the references tonull, which would make it eligible forgarbage collection. You just put the object back into the pool, and retrieve it when you need a new object.Reusing objects reduces the need to instantiate objects, which can be expensive. It also reduces the chances of thegarbage collector running, which can slow down your application. The following code illustrates the object poolingtechnique:package

}The SpritePool class creates a pool of new objects at the initialization of the application. ThegetSprite()methodreturns instances of these objects, and thedisposeSprite()method releases them. The code allows the pool to growwhen it has been consumed completely. It’s also possible to create a fixed-size pool where new objects would not beallocated when the pool is exhausted. Try to avoid creating new objects in loops, if possible. For more information, see“Freeing memory” on page

11. The following code uses the SpritePool class to retrieve new instances:const MAX_SPRITES:uint = 100;

const GROWTH_VALUE:uint = MAX_SPRITES >> 1;

const MAX_NUM:uint = 10;

SpritePool.initialize ( MAX_SPRITES, GROWTH_VALUE );

var currentSprite:Sprite;

var container:Sprite = SpritePool.getSprite();

addChild ( container );

for ( var i:int = 0; i< MAX_NUM; i++ )

{

for ( var j:int = 0; j< MAX_NUM; j++ )

{

currentSprite = SpritePool.getSprite();

currentSprite.graphics.beginFill ( 0x990000 );

currentSprite.graphics.drawCircle ( 10, 10, 10 );

currentSprite.x = j * (currentSprite.width + 5);

currentSprite.y = i * (currentSprite.width + 5);

container.addChild ( currentSprite );

}

}The following code removes all the display objects from the display list when the mouse is clicked, and reuses themlater for another task:11OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011stage.addEventListener ( MouseEvent.CLICK, removeDots );

function removeDots ( e:MouseEvent ):void

{

while (container.numChildren > 0 )

SpritePool.disposeSprite (container.removeChildAt(0) as Sprite );

}Note: The pool vector always references the Sprite objects. If you want to remove the object from memory completely, youwould need adispose()method on the SpritePool class, which would remove all remaining references.Freeing memoryDelete all references to objects to make sure that garbage collection is triggered.

You cannot launch the garbage collector directly in the release version of Flash Player. To make sure that an object isgarbage collected, delete all references to the object. Keep in mind that the olddeleteoperator used in ActionScript1.0 and 2.0 behaves differently in ActionScript 3.0. It can only be used to delete dynamic properties on a dynamicobject.Note: You can call the garbage collector directly in Adobe® AIR® and in the debug version of Flash Player.For example, the following code sets a Sprite reference tonull:

var mySprite:Sprite = new Sprite();

// Set the reference to null, so that the garbage collector removes

// it from memory

mySprite = null;Remember that when an object is set tonull, it is not necessarily removed from memory. Sometimes the garbagecollector does not run, if available memory is not considered low enough. Garbage collection is not predictable.Memory allocation, rather than object deletion, triggers garbage collection. When the garbage collector runs, it findsgraphs of objects that haven't been collected yet. It detects inactive objects in the graphs by finding objects thatreference each other, but that the application no longer uses. Inactive objects detected this way are deleted.In large applications, this process can be CPU-intensive and can affect performance and generate a noticeableslowdown in the application. Try to limit garbage collection passes by reusing objects as much as possible. Also, setreferences to null, when possible, so that the garbage collector spends less processing time finding the objects. Thinkof garbage collection as insurance, and always manage object lifetimes explicitly, when possible.Note: Setting a reference to a display object to null does not ensure that the object is frozen. The object continues consumeCPU cycles until it is garbage collected. Make sure that you properly deactivate your object before setting its reference tonull.The garbage collector can be launched using theSystem.gc()method, available in Adobe AIR and in the debugversion of Flash Player. The profiler bundled with Adobe® Flash® Builder™ allows you to start the garbage collectormanually. Running the garbage collector allows you to see how your application responds and whether objects arecorrectly deleted from memory.Note: If an object was used as an event listener, another object can reference it. If so, remove event listeners using theremoveEventListener()method before setting the references tonull.12OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011Fortunately, the amount of memory used by bitmaps can be instantly reduced. For example, the BitmapData classincludes adispose()method. The next example creates a BitmapData instance of 1.8 MB. The current memory inuse grows to 1.8 MB, and theSystem.totalMemoryproperty returns a smaller value:

trace(System.totalMemory / 1024);

// output: 43100

// Create a BitmapData instance

var image:BitmapData = new BitmapData(800, 600);

trace(System.totalMemory / 1024);

// output: 44964

Next, the BitmapData is manually removed (disposed) from memory and the memory use is once again checked:

trace(System.totalMemory / 1024);

// output: 43100

// Create a BitmapData instance

var image:BitmapData = new BitmapData(800, 600);

trace(System.totalMemory / 1024);

// output: 44964

image.dispose();

image = null;

trace(System.totalMemory / 1024);

// output: 43084Although thedispose()method removes the pixels from memory, the reference must still be set tonullto release itcompletely. Always call thedispose()method and set the reference tonullwhen you no longer need a BitmapDataobject, so that memory is freed immediately.Note: Flash Player 10.1 and AIR 1.5.2 introduce a new method calleddisposeXML()on the System class. This methodallows you to make an XML object immediately available for garbage collection, by passing the XML tree as a parameter.More Help topics“Freezing and unfreezing objects” on page

26Using bitmapsUsing vectors instead of bitmaps is good way to save memory. However, using vectors, especially in large numbers,dramatically increases the need for CPU or GPU resources. Using bitmaps is a good way to optimize rendering,because the runtime needs fewer processing resources to draw pixels on the screen than to render vector content.More Help topics“Manual bitmap caching” on page

5813OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011Bitmap downsamplingTo make better use of memory, 32-bit opaque images are reduced to 16-bit images when Flash Player detects a 16-bitscreen. This downsampling consumes half the memory resources, and images render more quickly. This feature isavailable only in Flash Player 10.1 for Windows Mobile.Note: Before Flash Player 10.1, all pixels created in memory were stored in 32 bits (4 bytes). A simple logo of 300 x 300pixels consumed 350 KB of memory (300*300*4/1024). With this new behavior, the same opaque logo consumes only 175KB. If the logo is transparent, it is not downsampled to 16 bits, and it keeps the same size in memory. This feature appliesonly to embedded bitmaps or runtime-loaded images (PNG, GIF, JPG).On mobile devices, it can be hard to tell the difference between an image rendered in 16 bits and the same imagerendered in 32 bits. For a simple image containing just a few colors, there is no detectable difference. Even for a morecomplex image, it is difficult to detect the differences. However, there can be some color degradation when zoomingin on the image, and a 16-bit gradient can look less smooth than the 32-bit version.BitmapData single referenceIt is important to optimize the use of the BitmapData class by reusing instances as much as possible. Flash Player 10.1and AIR 2.5 introduce a new feature for all platforms called BitmapData single reference. When creating BitmapDatainstances from an embedded image, a single version of the bitmap is used for all BitmapData instances. If a bitmap ismodified later, it is given its own unique bitmap in memory. The embedded image can be from the library or an[Embed] tag.Note: Existing content also benefits from this new feature, because Flash Player 10.1 and AIR 2.5 automatically reusebitmaps.When instantiating an embedded image, an associated bitmap is created in memory. Before Flash Player 10.1 and AIR2.5, each instance was given a separate bitmap in memory, as shown in the following diagram:Bitmaps in memory before Flash Player 10.1 and AIR 2.5In Flash Player 10.1 and AIR 2.5, when multiple instances of the same image are created, a single version of the bitmapis used for all BitmapData instances. The following diagram illustrates this concept:Memory DisplayedLogo InstanceLogo InstanceBitmap SourceBitmap Source14OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011Bitmaps in memory in Flash Player 10.1 and AIR 2.5This approach dramatically reduces the amount of memory used by an application with many bitmaps. The followingcode creates multiple instances of aStarsymbol:

const MAX_NUM:int = 18;

var star:BitmapData;

var bitmap:Bitmap;

for (var i:int = 0; i<MAX_NUM; i++)

{

for (var j:int = 0; j<MAX_NUM; j++)

{

star = new Star(0,0);

bitmap = new Bitmap(star);

bitmap.x = j * star.width;

bitmap.y = i * star.height;

addChild(bitmap)

}

}The following image shows the result of the code:Memory DisplayedLogo InstanceLogo InstanceBitmap Source15OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011Result of code to create multiple instances of symbolWith Flash Player 10, for example, the animation above uses about 1008 KB of memory. With Flash Player 10.1, on thedesktop and on a mobile device, the animation uses only 4 KB.The following code modifies one BitmapData instance:

const MAX_NUM:int = 18;

var star:BitmapData;

var bitmap:Bitmap;

for (var i:int = 0; i<MAX_NUM; i++)

{

for (var j:int = 0; j<MAX_NUM; j++)

{

star = new Star(0,0);

bitmap = new Bitmap(star);

bitmap.x = j * star.width;

bitmap.y = i * star.height;

addChild(bitmap)

}

}

var ref:Bitmap = getChildAt(0) as Bitmap;

ref.bitmapData.pixelDissolve(ref.bitmapData, ref.bitmapData.rect, newPoint(0,0),Math.random()*200,Math.random()*200, 0x990000);The following image shows the result of modifying oneStarinstance:16OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011Result of modifying one instanceInternally, the runtime automatically assigns and creates a bitmap in memory to handle the pixel modifications. Whena method of the BitmapData class is called, leading to pixel modifications, a new instance is created in memory, andno other instances are updated. The following figure illustrates the concept:Result in memory of modifying one bitmapIf one star is modified, a new copy is created in memory. The resulting animation uses about 8 KB in memory on FlashPlayer 10.1 and AIR 2.5.Memory DisplayedLogo InstanceLogo InstanceLogo InstancesetPixel()Bitmap SourceBitmap Source17OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011In the previous example, each bitmap is available individually for transformation. To create only the tiling effect, thebeginBitmapFill()method is the most appropriate method:

var container:Sprite = new Sprite();

var source:BitmapData = new Star(0,0);

// Fill the surface with the source BitmapData

container.graphics.beginBitmapFill(source);

container.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);

addChild(container);This approach produces the same result with only a single BitmapData instance created. To rotate the starscontinuously, instead of accessing each Star instance, use a Matrix object that is rotated on each frame. Pass this Matrixobject to thebeginBitmapFill()method:

var container:Sprite = new Sprite();

container.addEventListener(Event.ENTER_FRAME, rotate);

var source:BitmapData = new Star(0,0);

var matrix:Matrix = new Matrix();

addChild(container);

var angle:Number = .01;

function rotate(e:Event):void

{

// Rotate the stars

matrix.rotate(angle);

// Clear the content

container.graphics.clear();

// Fill the surface with the source BitmapData

container.graphics.beginBitmapFill(source,matrix,true,true);

container.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);

}Using this technique, no ActionScript loop is required to create the effect. The runtime does everything internally. Thefollowing image shows the result of transforming the stars:18OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011Result of rotating starsWith this approach, updating the original source BitmapData object automatically updates its use elsewhere on thestage, which can be a powerful technique. This approach would not, however, allow each star to be scaled individually,as in the previous example.Note: When using multiple instances of the same image, drawing depends on whether a class is associated with theoriginal bitmap in memory. If no class is associated with the bitmap, images are drawn as Shape objects with bitmap fills.Filters and dynamic bitmap unloadingAvoid filters, including filters processed through Pixel Bender.

Try to minimize the use of effects like filters, including filters processed in mobile devices through Pixel Bender. Whena filter is applied to a display object, the runtime creates two bitmaps in memory. These bitmaps are each the size ofthe display object. The first is created as a rasterized version of the display object, which in turn is used to produce asecond bitmap with the filter applied:19OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011Two bitmaps in memory when filter is appliedWhen modifying one of the properties of a filter, both bitmaps are updated in memory to create the resulting bitmap.This process involves some CPU processing and the two bitmaps can use a significant amount of memory.Flash Player 10.1 and AIR 2.5 introduce a new filtering behavior on all platforms. If the filter is not modified within 30seconds, or if it is hidden or offscreen, the memory used by the non-filtered bitmap is freed.This feature saves half the memory used by a filter on all platforms. For example, consider a text object with a blur filterapplied. The text in this case is used for simple decoration and is not modified. After 30 seconds, the non-filteredbitmap in memory is freed. The same result occurs if the text is hidden for 30 seconds or is offscreen. When one of thefilter properties is modified, the non-filtered bitmap in memory is recreated. This feature is called dynamic bitmapunloading. Even with these optimizations, be cautious with filters; they still require extensive CPU or GPU processingwhen being modified.As a best practice, use bitmaps created through an authoring tool, such as Adobe® Photoshop®, to emulate filters whenpossible. Avoid using dynamic bitmaps created at runtime in ActionScript. Using externally authored bitmaps helpsthe runtime to reduce the CPU or GPU load, especially when the filter properties do not change over time. If possible,create any effects that you need on a bitmap in an authoring tool. You can then display the bitmap in the runtimewithout performing any processing on it, which can be much faster.Direct mipmappingUse mipmapping to scale large images, if needed.

Another new feature available in Flash Player 10.1 and AIR 2.5 on all platforms is related to mipmapping. Flash Player9 and AIR 1.0 introduced a mipmapping feature that improved the quality and performance of downscaled bitmaps.Note: The mipmapping feature applies only to dynamically loaded images or embedded bitmaps. Mipmapping does notapply to display objects that have been filtered or cached. Mipmapping can be processed only if the bitmap has a widthand height that are even numbers. When a width or height that is an odd number is encountered, mipmapping stops. Forexample, a 250 x 250 image can be mipmapped down to 125 x 125, but it cannot be mipmapped further. In this case, atleast one of the dimensions is an odd number. Bitmaps with dimensions that are powers of two achieve the best results,for example: 256 x 256, 512 x 512, 1024 x 1024, and so on.Memory DisplayedResultBitmap version non-filteredBitmap version filtered20OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011As an example, imagine that a 1024 x 1024 image is loaded, and a developer wants to scale the image to create athumbnail in a gallery. The mipmapping feature renders the image properly when scaled by using the intermediatedownsampled versions of the bitmap as textures. Previous versions of the runtime created intermediate downscaledversions of the bitmap in memory. If a 1024 x 1024 image was loaded and displayed at 64 x 64, older versions of theruntime would create every half-sized bitmap. For example, in this case 512 x 512, 256 x 256, 128 x 128, and 64 x 64bitmaps would be created.Flash Player 10.1 and AIR 2.5 now support mipmapping directly from the original source to the destination sizerequired. In the previous example, only the 4 MB (1024 x 1024) original bitmap and the 16 KB (64 x 64) mipmappedbitmap would be created.The mipmapping logic also works with the dynamic bitmap unloading feature. If only the 64 x 64 bitmap is used, the4-MB original bitmap is freed from memory. If the mipmap must be recreated, then the original is reloaded. Also, ifother mipmapped bitmaps of various sizes are required, the mipmap chain of bitmaps is used to create the bitmap. Forexample, if a 1:8 bitmap must be created, the 1:4 and 1:2 and 1:1 bitmaps are examined to determine which is loadedinto memory first. If no other versions are found, the 1:1 original bitmap is loaded from the resource and used.The JPEG decompressor can perform mipmapping within its own format. This direct mipmapping allows a largebitmap to be decompressed directly to a mipmap format without loading the entire uncompressed image. Generatingthe mipmap is substantially faster, and memory used by large bitmaps is not allocated and then freed. The JPEG imagequality is comparable to the general mipmapping technique.Note: Use mipmapping sparingly. Although it improves the quality of downscaled bitmaps, it has an impact onbandwidth, memory, and speed. In some cases, a better option can be to use a pre-scaled version of the bitmap from anexternal tool and import it into your application. Don’t start with large bitmaps if you only intend to scale them down.Using 3D effectsConsider creating 3D effects manually.

Flash Player 10 and AIR 1.5 introduced a 3D engine, which allows you to apply perspective transformation on displayobjects. You can apply these transformations using therotationXandrotationYproperties or with thedrawTriangles()method of the Graphics class. You can also apply depth with thezproperty. Keep in mind that eachperspective-transformed display object is rasterized as a bitmap and therefore requires more memory.The following figure illustrates the anti-aliasing produced by the rasterization when using perspective transformation:21OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011Anti-aliasing resulting from perspective transformationThe anti-aliasing is a result of vector content being dynamically rasterized as a bitmap. This anti-aliasing happenswhen you use 3D effects in the desktop version of AIR and Flash Player, and in AIR 2.0.1 and AIR 2.5 for mobile.However, anti-aliasing is not applied on Flash Player for mobile devices.If you can create your 3D effect manually without relying on the native API, that can reduce memory usage. However,the new 3D features introduced in Flash Player 10 and AIR 1.5 make texture mapping easier, because of methods likedrawTriangles(), which handles texture mapping natively.As a developer, decide whether the 3D effect you want to create provides better performance if it is processed throughthe native API or manually. Consider ActionScript execution and rendering performance, as well as memory usage.In AIR 2.0.1 and AIR 2.5 mobile applications in which you set therenderModeapplication property toGPU, the GPUdoes the 3D transformations. However, if therenderModeisCPU, the CPU, not the GPU, performs the 3Dtransformations. In Flash Player 10.1 applications, the CPU performs the 3D transformations.When the CPU does the 3D transformations, consider that applying any 3D transformation to a display object requirestwo bitmaps in memory. One bitmap is for the source bitmap, and a second one is for the perspective-transformedversion. In this way, 3D transformations work in a similar way to filters. As a result, use the 3D properties sparinglywhen the CPU does the 3D transformations.Text objects and memoryUse the Adobe® Flash® Text Engine for read-only text; use TextField objects for input text.

Flash Player 10 and AIR 1.5 introduced a powerful new text engine, the Adobe Flash Text Engine (FTE), that conservessystem memory. However, the FTE is a low-level API that requires an additional ActionScript 3.0 layer on top of it,provided in the flash.text.engine package.For read-only text, it’s best to use the Flash Text Engine, which offers low memory usage and better rendering. Forinput text, TextField objects are a better choice, because less ActionScript code is required to create typical behaviors,such as input handling and word-wrap.22OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMConserving memoryLast updated 9/28/2011More Help topics“Rendering text objects” on page

The ActionScript 3.0 event model is based on the concept of object dispatching. The event model is object-orientedand optimized for code reuse. ThedispatchEvent()method loops through the list of listeners and calls the eventhandler method on each registered object. However, one of the drawbacks of the event model is that you are likely tocreate many objects over the lifetime of your application.Imagine that you must dispatch an event from the timeline, indicating the end of an animation sequence. Toaccomplish the notification, you can dispatch an event from a specific frame in the timeline, as the following codeillustrates:dispatchEvent( new Event ( Event.COMPLETE ) );The Document class can listen for this event with the following line of code:addEventListener( Event.COMPLETE, onAnimationComplete );Although this approach is correct, using the native event model can be slower and consume more memory than usinga traditional callback function. Event objects must be created and allocated in memory, which creates a performanceslowdown. For example, when listening to the Event.ENTER_FRAME event, a new event object is created on eachframe for the event handler. Performance can be especially slow for display objects, due to the capture and bubblingphases, which can be expensive if the display list is complex.23Last updated 9/28/2011Chapter 3: Minimizing CPU usageAnother important area of focus for optimization is CPU usage. Optimizing CPU processing improves performance,and as a result, battery life on mobile devices.Flash Player 10.1 enhancements for CPU usageFlash Player 10.1 introduces two new features that help save CPU processing. The features involve pausing andresuming SWF content when it goes offscreen, and limiting the number of Flash Player instances on a page.Pause and resumeNote: The pause and resume feature does not apply to Adobe® AIR® applications.To optimize CPU and battery usage, Flash Player 10.1 introduces a new feature on mobile platforms (and netbooks)related to inactive instances. This feature allows you to limit CPU usage by pausing and resuming the SWF file whencontent goes off and on the screen. With this feature, Flash Player releases as much memory as possible by removingany objects that can be recreated when the playing of content is resumed. Content is considered offscreen when theentire content is offscreen.Two scenarios cause the SWF content to be offscreen:•The user scrolls the page and causes the SWF content to move offscreen.In this case, if there is any audio or video playback, content continues to play, but rendering is stopped. If there isno audio or video playing, to ensure that the playback or ActionScript execution is not paused, set thehasPriority

HTML parameter to true. However, keep in mind that SWF content rendering is paused when content is offscreenor hidden, regardless of the value of thehasPriorityHTML parameter.•A tab is opened in the browser, which causes the SWF content to move to the background.In this case, regardless of the value of thehasPriorityHTML tag, the SWF content is slowed down to 2 fps. Audioand video playback is stopped and no content rendering is processed unless the SWF content becomes visible again.Instance managementNote: The instance management feature does not apply to Adobe® AIR® applications.Use thehasPriorityHTML parameter to delay loading of offscreen SWF files.

Flash Player 10.1 introduces a new HTML parameter calledhasPriority:

<param name="hasPriority" value="true" />24OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMMinimizing CPU usageLast updated 9/28/2011This feature limits the number of Flash Player instances that are started on a page. Limiting the number of instanceshelps conserve CPU and battery resources. The idea is to assign a specific priority to SWF content, giving some contentpriority over other content on a page. Consider a simple example: a user is browsing a website and the index page hoststhree different SWF files. One of them is visible, another one is partially visible onscreen, and the last one is offscreen,requiring scrolling. The first two animations are started normally, but the last one is deferred until it becomes visible.This scenario is the default behavior when thehasPriorityparameter is not present or set tofalse. To ensure thata SWF file is started, even if it is offscreen, set thehasPriorityparameter totrue. However, regardless of the valueof thehasPriorityparameter, a SWF file that is not visible to the user always has its rendering paused.Note: If available CPU resources become low, Flash Player instances are no longer started automatically, even if thehasPriorityparameter is set totrue. If new instances are created through JavaScript after the page has been loaded,those instances will ignore thehasPriorityflag. Any 1x1 pixel or 0x0 pixel content is started, preventing helper SWFfiles from being deferred if the webmaster fails to include thehasPriorityflag. SWF files can still be started whenclicked, however. This behavior is called “click to play.”The following diagrams show the effects of setting thehasPriorityparameter to different values:Effects of different values for the hasPriority parametervisible area on user’s deviceSWFhasPriority set tofalse or not presentSWF movie startedSWF movie not startedSWFhasPriority set to falseor not presentSWFhasPriorityset to falseor not present25OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMMinimizing CPU usageLast updated 9/28/2011Effects of different values for the hasPriority parameterSleep modeFlash Player 10.1 and AIR 2.5 introduce a new feature on mobile devices that helps save CPU processing, and as aresult, battery life. This feature involves the backlight found on many mobile devices. For example, if a user running amobile application is interrupted and stops using the device, the runtime detects when the backlight goes into sleepmode. It then drops the frame rate to 4 frames per second (fps), and pauses rendering. For AIR applications, sleepmode also begins when the application moves to the background.ActionScript code continues to execute in sleep mode, similar to setting theStage.frameRateproperty to 4 fps. Butthe rendering step is skipped, so the user cannot see that the player is running at 4 fps. A frame rate of 4 fps was chosen,rather than zero, because it allows all the connections to remain open (NetStream, Socket, and NetConnection).Switching to zero would break open connections. A 250 ms refresh rate was chosen (4 fps) because many devicemanufacturers use this frame rate as their refresh rate. Using this value keeps the frame rate of the runtime in the sameballpark as the device itself.Note: When the runtime is in sleep mode, theStage.frameRateproperty returns the frame rate of the original SWF file,rather than 4 fps.When the backlight goes back into on mode, rendering is resumed. The frame rate returns to its original value.Consider a media player application in which a user is playing music. If the screen goes into sleep mode, the runtimeresponds based on the type of content being played. Here is a list of situations with the corresponding runtimebehavior:•The backlight goes into sleep mode and non-A/V content is playing: The rendering is paused and the frame rate isset to 4 fps.visible area on user’s deviceSWFhasPriority set tofalse or not presentSWFhasPriority set to trueSWF movie startedSWF movie not startedSWFhasPriorityset to falseor not present26OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMMinimizing CPU usageLast updated 9/28/2011•The backlight goes into sleep mode and A/V content is playing: the runtime forces the backlight to be always on,continuing the user experience.•The backlight goes from sleep mode to on mode: the runtime sets the frame rate to the original SWF file frame ratesetting and resumes rendering.•Flash Player is paused while A/V content is played: Flash Player resets the backlight state to the default systembehavior because A/V is no longer playing.•Mobile device receives a phone call while A/V content is played: The rendering is paused and the frame rate is setto 4 fps.•The backlight sleep mode is disabled on a mobile device: the runtime behaves normally.When the backlight goes into sleep mode, rendering pauses and the frame rate slows down. This feature saves CPUprocessing, but it cannot be relied upon on to create a real pause, as in a game application.Note: No ActionScript event is dispatched when the runtime enters or leaves sleep mode.Freezing and unfreezing objectsFreeze and unfreeze objects properly by using theREMOVED_FROM_STAGEandADDED_TO_STAGEevents.

To optimize your code, always freeze and unfreeze your objects. Freezing and unfreezing are important for all objects,but are especially important for display objects. Even if display objects are no longer in the display list and are waitingto be garbage collected, they could still be using CPU-intensive code. For example, they can still be usingEvent.ENTER_FRAME. As a result, it is critical to freeze and unfreeze objects properly with theEvent.REMOVED_FROM_STAGEandEvent.ADDED_TO_STAGEevents. The following example shows a movie clipplaying on stage that interacts with the keyboard:// Listen to keyboard events

}Movie clip that interacts with keyboardWhen the Remove button is clicked, the movie clip is removed from the display list:28OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMMinimizing CPU usageLast updated 9/28/2011

// Show or remove running boy

showBtn.addEventListener (MouseEvent.CLICK,showIt);

removeBtn.addEventListener (MouseEvent.CLICK,removeIt);

function showIt (e:MouseEvent):void

{

addChild (runningBoy);

}

function removeIt(e:MouseEvent):void

{

if (contains(runningBoy)) removeChild(runningBoy);

}Even when removed from the display list, the movie clip still dispatches theEvent.ENTER_FRAMEevent. The movieclip still runs, but it is not rendered. To handle this situation correctly, listen to the proper events and remove eventlisteners, to prevent CPU-intensive code from being executed:

}When the Show button is pressed, the movie clip is restarted, it listens toEvent.ENTER_FRAMEevents again, and thekeyboard correctly controls the movie clip.Note: If a display object is removed from the display list, setting its reference tonullafter removing it does not ensurethat the object is frozen. If the garbage collector doesn’t run, the object continues to consume memory and CPU processing,even though the object is no longer displayed. To make sure that the object consumes the least CPU processing possible,make sure that you completely freeze it when removing it from the display list.Starting with Flash Player 10 and AIR 1.5, the following behavior also occurs. If the playhead encounters an emptyframe, the display object is automatically frozen even if you did not implement any freezing behavior.The concept of freezing is also important when loading remote content with the Loader class. When using the Loaderclass with Flash Player 9 and AIR 1.0, it was necessary to manually freeze content by listening to theEvent.UNLOAD

event dispatched by the LoaderInfo object. Every object had to be manually frozen, which was a non-trivial task. FlashPlayer 10 and AIR 1.5 introduced an important new method on the Loader class calledunloadAndStop(). Thismethod allows you to unload a SWF file, automatically freeze every object in the loaded SWF file, and force the garbagecollector to run.In the following code, the SWF file is loaded and then unloaded using theunload()method, which requires moreprocessing and manual freezing:29OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMMinimizing CPU usageLast updated 9/28/2011

var loader:Loader = new Loader();

loader.load ( new URLRequest ( "content.swf" ) );

addChild ( loader );

stage.addEventListener ( MouseEvent.CLICK, unloadSWF );

function unloadSWF ( e:MouseEvent ):void

{

// Unload the SWF file with no automatic object deactivation

// All deactivation must be processed manually

loader.unload();

}A best practice is to use theunloadAndStop()method, which handles the freezing natively and forces the garbagecollecting process to run:

var loader:Loader = new Loader();

loader.load ( new URLRequest ( "content.swf" ) );

addChild ( loader );

stage.addEventListener ( MouseEvent.CLICK, unloadSWF );

function unloadSWF ( e:MouseEvent ):void

{

// Unload the SWF file with automatic object deactivation

// All deactivation is handled automatically

loader.unloadAndStop();

}The following actions occur when theunloadAndStop()method is called:•Sounds are stopped.•Listeners registered to the SWF file’s main timeline are removed.•Timer objects are stopped.•Hardware peripheral devices (such as camera and microphone) are released.•Every movie clip is stopped.•Dispatching ofEvent.ENTER_FRAME,Event.FRAME_CONSTRUCTED,Event.EXIT_FRAME,Event.ACTIVATEandEvent.DEACTIVATEis stopped.Activate and deactivate eventsUseEvent.ACTIVATEandEvent.DEACTIVATEevents to detect background inactivity and optimize yourapplication appropriately.30OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMMinimizing CPU usageLast updated 9/28/2011Two events (Event.ACTIVATEandEvent.DEACTIVATE) can assist you in fine-tuning your application so that it usesthe fewest CPU cycles possible. These events allow you to detect when the runtime gains or loses focus. As a result,code can be optimized to react to context changes. The following code listens to both events and dynamically changesthe frame rate to zero when the application loses its focus. For example, the animation can lose focus when the userswitches to another tab or puts the application into the background:var originalFrameRate:uint = stage.frameRate;

var standbyFrameRate:uint = 0;

stage.addEventListener ( Event.ACTIVATE, onActivate );

stage.addEventListener ( Event.DEACTIVATE, onDeactivate );

function onActivate ( e:Event ):void

{

// restore original frame rate

stage.frameRate = originalFrameRate;

}

function onDeactivate ( e:Event ):void

{

// set frame rate to 0

stage.frameRate = standbyFrameRate;

}When the application gains focus again, the frame rate is reset to its original value. Instead of changing the frame ratedynamically, you could also consider making other optimizations, such as freezing and unfreezing objects.The activate and deactivate events allow you to implement a similar mechanism to the "Pause and Resume" featuresometimes found on mobile devices and Netbooks.More Help topics“Application frame rate” on page

When using an interactive object, such as a MovieClip or Sprite object, the runtime executes native code to detect andhandle mouse interactions. Detecting mouse interaction can be CPU-intensive when many interactive objects areshown onscreen, especially if they overlap. An easy way to avoid this processing is to disable mouse interactions onobjects that do not require any mouse interaction. The following code illustrates the use of themouseEnabledandmouseChildrenproperties:31OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMMinimizing CPU usageLast updated 9/28/2011// Disable any mouse interaction with this InteractiveObject

Timers are preferred overEvent.ENTER_FRAMEevents for non-animated content that executes for a long time.In ActionScript 3.0, there are two ways of calling a function at specific intervals. The first approach is to use theEvent.ENTER_FRAMEevent dispatched by display objects (DisplayObject). The second approach is to use a timer.ActionScript developers frequently use theENTER_FRAMEevent approach. TheENTER_FRAMEevent is dispatched onevery frame. As a result, the interval at which the function is called is related to the current frame rate. The frame rateis accessible through theStage.frameRateproperty. However, in some cases, using a timer can be a better choicethan using theENTER_FRAMEevent. For example, if you don’t use animation, but would like your code called at specificintervals, using a timer can be a better choice.A timer can behave in a similar way to anENTER_FRAMEevent, but an event can be dispatched without being tied tothe frame rate. This behavior can offer some significant optimization. Consider a video player application as anexample. In this case, you do not need to use a high frame rate, because only the application controls are moving.Note: The frame rate does not affect the video, because the video is not embedded in the timeline. Instead, the video isloaded dynamically through progressive downloading or streaming.In this example, the frame rate is set to a low value of 10 fps. The timer updates the controls at a rate of one update persecond. The higher update rate is made possible by theupdateAfterEvent()method, which is available on theTimerEvent object. This method forces the screen to be updated each time the timer dispatches an event, if needed.The following code illustrates the idea:32OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMMinimizing CPU usageLast updated 9/28/2011// Use a low frame rate for the application

stage.frameRate = 10;

// Choose one update per second

var updateInterval:int = 1000;

var myTimer:Timer = new Timer(updateInterval,0);

myTimer.start();

myTimer.addEventListener( TimerEvent.TIMER, updateControls );

function updateControls( e:TimerEvent ):void

{

// Update controls here

// Force the controls to be updated on screen

e.updateAfterEvent();

}Calling theupdateAfterEvent()method does not modify the frame rate. It just forces the runtime to update thecontent onscreen that has changed. The timeline still runs at 10 fps. Remember that timers andENTER_FRAMEeventsare not perfectly accurate on low performance devices, or if event handler functions contain code that requires heavyprocessing. Just like the SWF file frame rate, the update frame rate of the timer can vary in some situations.Minimize the number of Timer objects and registeredenterFramehandlers in your application.

Each frame, the runtime dispatches anenterFrameevent to each display object in its display list. Although you canregister listeners for theenterFrameevent with multiple display objects, doing so means that more code is executedeach frame. Instead, consider using a single centralizedenterFramehandler that executes all the code that is to runeach frame. By centralizing this code, it is easier to manage all the code that is running frequently.Likewise, if you’re using Timer objects, there is overhead associated with creating and dispatching events frommultiple Timer objects. If you must trigger different operations at different intervals, here are some suggestedalternatives:•Use a minimal number of Timer objects and group operations according to how frequently they happen.For example, use one Timer for frequent operations, set to trigger every 100 milliseconds. Use another Timer forless-frequent or background operations, set to trigger every 2000 milliseconds.•Use a single Timer object, and have operations triggered at multiples of the Timer object’sdelayproperty interval.For example, suppose you have some operations that are expected to happen every 100 milliseconds, and othersthat you want to happen every 200 milliseconds. In that case, use a single Timer object with adelayvalue of 100milliseconds. In thetimerevent handler, add a conditional statement that only runs the 200-millisecondoperations every other time. The following example demonstrates this technique:33OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMMinimizing CPU usageLast updated 9/28/2011var timer:Timer = new Timer(100);

timer.addEventListener(TimerEvent.Timer, timerHandler);

timer.start();

var offCycle:Boolean = true;

function timerHandler(event:TimerEvent):void

{

// Do things that happen every 100 ms

if (!offCycle)

{

// Do things that happen every 200 ms

}

offCycle = !offCycle;

}Stop Timer objects when not in use.

If a Timer object’stimerevent handler only performs operations under certain conditions, call the Timer object’sstop()method when none of the conditions are true.InenterFrameevent or Timer handlers, minimize the number of changes to the appearance of display objects thatcause the screen to be redrawn.Each frame, the rendering phase redraws the portion of the stage that has changed during that frame. If the redrawregion is large, or if it’s small but contain a large quantity or complex display objects, the runtime needs more time forrendering. To test the amount of redrawing required, use the “show redraw regions” feature in the debug Flash Playeror AIR.For more information about improving performance for repeated actions, see the following article:•Writing well-behaved, efficient, AIR applications(article and sample application by Arno Gourdol)More Help topics“Isolating behaviors” on page

61Tweening syndromeTo save CPU power, limit the use of tweening, which saves CPU processing, memory, and battery life.

Designers and developers producing content for Flash on the desktop tend to use many motion tweens in theirapplications. When producing content for mobile devices with low performance, try to minimize the use of motiontweens. Limiting their use helps content run faster on low-tier devices.34Last updated 9/28/2011Chapter 4: ActionScript 3.0 performanceVector class versus Array classUse the Vector class instead of the Array class, when possible.

The Vector class allows faster read and write access than the Array class.A simple benchmark shows the benefits of the Vector class over the Array class. The following code shows abenchmark for the Array class:var coordinates:Array = new Array();

var started:Number = getTimer();

for (var i:int = 0; i< 300000; i++)

{

coordinates[i] = Math.random()*1024;

}

trace(getTimer() - started);

// output: 107The following code shows a benchmark for the Vector class:

var coordinates:Vector.<Number> = new Vector.<Number>();

var started:Number = getTimer();

for (var i:int = 0; i< 300000; i++)

{

coordinates[i] = Math.random()*1024;

}

trace(getTimer() - started);

// output: 72The example can be further optimized by assigning a specific length to the vector and setting its length to fixed:// Specify a fixed length and initialize its length

var coordinates:Vector.<Number> = new Vector.<Number>(300000, true);

var started:Number = getTimer();

for (var i:int = 0; i< 300000; i++)

{

coordinates[i] = Math.random()*1024;

}

trace(getTimer() - started);

// output: 4835OPTIMIZING PERFORMANCE FOR THE FLASH PLATFORMActionScript 3.0 performanceLast updated 9/28/2011If the size of the vector is not specified ahead of time, the size increases when the vector runs out of space. Each timethe size of the vector increases, a new block of memory is allocated. The current content of the vector is copied into thenew block of memory. This extra allocation and copying of data hurts performance. The above code is optimized forperformance by specifying the initial size of the vector. However, the code is not optimized for maintainability. To alsoimprove maintainability, store the reused value in a constant:

// Store the reused value to maintain code easily

const MAX_NUM:int = 300000;

var coordinates:Vector.<Number> = new Vector.<Number>(MAX_NUM, true);

var started:Number = getTimer();

for (var i:int = 0; i< MAX_NUM; i++)

{

coordinates[i] = Math.random()*1024;

}

trace(getTimer() - started);

// output: 47Try to use the Vector object APIs, when possible, as they are likely to run faster.Drawing APIUse the drawing API for faster code execution.

Flash Player 10 and AIR 1.5 provided a new drawing API, which allows you to get better code execution performance.This new API does not provide rendering performance improvement, but it can dramatically reduce the number oflines of code you have to write. Fewer lines of code can provide better ActionScript execution performance.The new drawing API includes the following methods:•drawPath()•drawGraphicsData()•drawTriangles()Note: This discussion does not focus on thedrawTriangles()method, which is related to 3D. However, this method canimprove ActionScript performance, because it handles native texture mapping.The following code explicitly calls the appropriate method for each line being drawn: