ActionScript.org Flash, Flex and ActionScript Resources - http://www.actionscript.org/resources
Flash Hacks
http://www.actionscript.org/resources/articles/579/1/Flash-Hacks/Page1.html
Sham Bhangal
Sham Bhangal is an author of and contributor to numerous books on Flash and ActionScript, including Foundation ActionScript for Flash MX, Flash MX Designer's ActionScript Reference, and Macromedia Flash MX Upgrade Essentials.  
By Sham Bhangal
Published on March 31, 2007
 
This article focuses on Performance and Optimization of your Flash file and ActionScript code. Excerpted from O'Reilly's excellent "Flash Hacks: 100 Industrial-Strength Tips & Tools" (Chapter 9) it's a great read.

Table of Contents

Copyright © 2004 O'Reilly Media, Inc. All Rights Reserved.
Flash Hacks: 100 Industrial-Stength Tips & Tools
By Sham Bhangal
June 2004
ISBN: 0-596-00645-4
http://www.oreilly.com/catalog/flashhks/index.html
Available from booksellers or direct from O'Reilly Media, www.oreilly.com.

Cover image
This content is excerpted from the above-named O'Reilly publication, with permission, by agreement with ActionScript.org.

Hacks #65-73
Optimize Filesize and Download Time
Optimize Graphics
65. Beat Flash File Bloat
Why the Big File?
The Fix
Final Thoughts
66. Bandwidth Testing for Complex Sites
Final Thoughts
67. Hide Low-Quality Settings
Use Noncontrasting Colors
Use Horizontal/Vertical and Fast-Moving Shapes
Use Pixel Fonts
Final Thoughts
68. Optimize Graphics for Performance
Design with Speed in Mind
Create and Test Optimized Graphics
Final Thoughts
69. Benchmark Runtime Performance
Final Thoughts
70. Adjust the Animation Complexity Dynamically
Calculate the Achieved Frame Rate
Adjust the Complexity Based on Performance
Final Thoughts
71. Performance Budget
Areas of Focus
Set Process Priorities
Implementation
Final Thoughts
72. Substitute Bitmaps for Vectors
Example One: Bitmaps Move Faster than Do Vectors
Example Two: Avoid Antialias Calculations
Final Thoughts
73. Optimize Component Downloading and Usage
Final Thoughts

Hacks #65-73

Flash's animation engine isn't the fastest one around because the Flash Player is optimized for a small download size, not for performance. Also, it is designed with web use in mind; therefore, it is optimized for small, low-bandwidth files rather than large, complex animation. In order to maintain its small footprint and ensure maximum compatibility, the Flash Player does not support hardware acceleration. Therefore, performance issues are often paramount for the Flash designer.

Three areas of possible optimization in Flash are as follows:

  • Reduce download time by creating efficiencies in content filesizes or changing the way content is downloaded [Hack #73]

  • Increase animation performance by optimizing graphics for fast redraw

  • Increase computing performance by writing code that executes quickly

Each point is considered in greater detail next.

Optimize Filesize and Download Time

Flash started off as a simple vector-based web animation plugin but is now routinely used for more bandwidth-heavy applications. Take care to ensure that the user is not kept waiting for content to load. The only way to ensure the lowest possible wait times is to test your site often during production.

Prior to the Flash MX 2004 Version 7.0.1 update, the built-in Bandwidth Profiler offered little help in modeling realistic web conditions for sites using multiple SWFs or other external assets. Although the latest version can test multiple SWFs and account for externally loaded assets, it still does not properly handle shared fonts, nor does it allow you to test your site from within a browser.

Third-party tools [Hack #66] help overcome the limitations of the Bandwidth Profiler and enable you to test the whole site (i.e., both Flash and non-Flash assets) under bandwidth-limited conditions using the browser.



Optimize Graphics

Copyright © 2004 O'Reilly Media, Inc. All Rights Reserved.
Flash Hacks: 100 Industrial-Stength Tips & Tools
By Sham Bhangal
June 2004
ISBN: 0-596-00645-4
http://www.oreilly.com/catalog/flashhks/index.html
Available from booksellers or direct from O'Reilly Media, www.oreilly.com.

Cover image
This content is excerpted from the above-named O'Reilly publication, with permission, by agreement with ActionScript.org.

Flash's ubiquity is largely attributable to the small download size of the Flash Player and the ability to create low-bandwidth content. However, the filesize optimization comes at the cost of reduced performance as you increase complexity.

Vectors graphics are more compact than other image formats because vectors define the math (points, curves, and fills) required to draw the image at runtime rather than the raw graphic data. However, converting the vector data to the final image is time consuming and must be done whenever there is a change in appearance or position of a graphic. If your image contains complex shape outlines or large fill areas, and they also change every frame, your animations might run slowly.

In this chapter, we explore several ways of reducing the performance hit caused by using vectors, including how to design graphics [Hack #68] and when to substitute bitmaps for vector images [Hack #72] .

Increase Code Performance

ActionScript is not compiled to native machine code like some languages (such as C++). Instead it is converted to bytecode, which is faster than an interpreted language but not as fast as native code. Although ActionScript can be slow, in most multimedia presentations, the assets such as graphics, audio, and video—and not the code—are often the limiting performance factor. Furthermore, the overall performance (or apparent performance from a user perspective) is also affected by download times and not just runtime execution. Of course, for a Rich Internet Application accessing a back-end database, performance might depend on the speed of database queries, data transmission, and text rendering.

Many hacks throughout this book cover ActionScript optimization. Furthermore:

  • Flash Player 7 is already optimized for code that uses lots of function calls and local variables [Hack #100], and older performance tricks are no longer as necessary.

  • Many optimization techniques are not specific to ActionScript but simply well-known techniques for writing code in any language without an optimizing compiler. For example, loops are faster if you remove items that don't change with every loop iteration and place them outside the loop instead.

  • If your code runs slowly, it is often a sign that you need to reduce the scope of your application or look for a hack that solves the problem in a different way. You should identify and remove bottlenecks, for example, by optimizing your graphics.

  • Often performance is about perception [Hack #71] . If you attempt to perform too much work in a single frame, Flash doesn't have time to render the Stage, and the user perceives a slowdown. If you break up the amount of work being performed into smaller chunks, Flash can refresh the Stage at the prescribed frame rate, and there is no perceived slowdown.

Although properly written ActionScript doesn't usually constitute a bottleneck, improvements can always be made. For those with an interest in ActionScript optimization, have a look at the following links:

  • gotoAndPlay (http://www.gotoandplay.it/_articles/2004/01/as_optimizations.php) offers a tutorial on ActionScript optimization.

  • Odd Hammer (http://www.oddhammer.com/actionscriptperformance) offers performance benchmarks of various ActionScript optimization techniques in different versions of the Flash Player.

Throughout this chapter, we'll explore ways to analyze and optimize performance in areas that are most likely to meaningfully affect runtime performance, download times, and the user experience. As with most topics, the optimal techniques depend on the situation, and there is often a trade-off between, say, performance versus convenience or download times versus runtime performance. The following hacks will help you make intelligent choices for your individual projects.

You can find numerous other optimization-related hacks throughout the book, such as how to optimize sound [Hack #58] and optimize character animations [Hack #28] .


Beat Flash File Bloat

Copyright © 2004 O'Reilly Media, Inc. All Rights Reserved.
Flash Hacks: 100 Industrial-Stength Tips & Tools
By Sham Bhangal
June 2004
ISBN: 0-596-00645-4
http://www.oreilly.com/catalog/flashhks/index.html
Available from booksellers or direct from O'Reilly Media, www.oreilly.com.

Cover image
This content is excerpted from the above-named O'Reilly publication, with permission, by agreement with ActionScript.org.

You may find that your FLA gets bigger every time you save it, even if you delete unused assets such as bitmaps and sounds. Beat the bloat with this hack.

When deploying Flash content online, filesize is the name of the game. The smaller the file you deploy, the faster it downloads. When compiling a FLA into a SWF, Flash omits unused assets in the Library [Hack #73] . However, the source FLA file contains not only unused Library assets, but even old assets that you have deleted from the Library! This is the cause of Flash FLA file bloat. It doesn't affect SWFs, but it is something to be aware of nonetheless.

In versions of Flash prior to Flash MX 2004, you will find that your files get larger each time you save them using File→Save, even after you delete unused content from them. Although Flash MX 2004's File→Save and Compact option reduces the FLA file's size, this option isn't available in prior versions of Flash. Furthermore, saving the FLA in Flash MX 2004 format prevents you from reopening the file in previous versions (although Flash MX 2004 and Flash MX Professional 2004 share the same file format).

Why the Big File?

You may wonder what causes the file bloat in the first place. In all versions of Flash, saving a FLA using File→Save adds only incremental changes to the FLA (known as an incremental save or fast save). Flash doesn't optimize the saved file by removing things you've deleted.

You can see this for yourself by creating a new Flash FLA file and importing a large media file (such as a bitmap or sound file). Then, save the file with File→Save or Ctrl-S (Windows) or

-S (Mac) and note the file's size. Then delete the large media asset from both the Stage and the Library and resave the file with File→Save. You will see that the filesize remains constant even after deleting the large assets!

This is the root of the bloat problem; as you make changes to a FLA file, the deletions are never removed from the saved file. This can also be problematic if you delete some embarrassing or proprietary content and then inadvertently pass it onto a client (granted, the client would need to decompile the FLA [Hack #98] to get at it, but it is always a good idea to cover your tracks). Although you ordinarily would publish only SWF files, you should compact FLA files when, say, posting them as examples on the Web or transmitting them to clients or other developers.

The Fix

You can force Flash to compact a FLA file in two ways:

Save the file using File→Save and Compact (Flash MX 2004 and Flash MX Professional 2004 only)

This option forces Flash to remove unnecessary information during the save. Flash has to rewrite the entire file, so the operation may take longer, depending on the amount of content to save. You won't be able to reopen the file in previous versions of Flash, so be careful to retain backups of the legacy FLAs! It is a good idea to save a backup under another name in case the compact operation fails for some reason.

Save and rename the file using File→Save As (all versions of Flash)

This option does the same thing as File→Save and Compact but it assumes you will rename the file. Using another name is a good idea in case the file save operation fails, but you can save it using the original filename by clicking Yes when warned that a file of that name already exists.

So, why doesn't Macromedia change it so that the File→Save option performs a save and compact? Well, incremental saves can be considerably faster. Therefore, the optimal workflow is:

  • Press Ctrl-S (or

    -S) to save the file every so often. This saves the file instantaneously so you can carry on without any pause.

  • Make a backup of your file periodically to avoid losing any work or allowing you to go back to a previous version if you need to for some reason.

  • Select File→Save As or File→Save and Compact on occasion (such as at the end of the day or before archiving files) to compact the file.

  • Before permanently archiving a FLA file, save a backup copy. Then delete unused assets from the Library (bearing in mind that assets used via ActionScript should not be deleted). Then save and compact the file using one of the preceding techniques in order to minimize the FLA for archival purposes.

Final Thoughts

Although the bloat quirk is addressed in Flash MX 2004, you still need to know what's going on to manage it effectively within your workflow. Flash development often incorporates many design and asset changes, so files can get bloated very quickly. Minimizing the size of FLA files makes them load faster in the authoring tool and saves space when archiving or transmitting the FLA. Similar issues exist in many other commercial software products, including Macromedia Director and Microsoft Word.



Bandwidth Testing for Complex Sites

Copyright © 2004 O'Reilly Media, Inc. All Rights Reserved.
Flash Hacks: 100 Industrial-Stength Tips & Tools
By Sham Bhangal
June 2004
ISBN: 0-596-00645-4
http://www.oreilly.com/catalog/flashhks/index.html
Available from booksellers or direct from O'Reilly Media, www.oreilly.com.

Cover image
This content is excerpted from the above-named O'Reilly publication, with permission, by agreement with ActionScript.org.


Use WebSpeed Simulator to sidestep the Bandwidth Profiler's inability to simulate bandwidth performance when testing through the browser (i.e., real-world conditions).

When creating a site, you want to know how long it will take to download at a particular connection speed. This helps you ensure the best experience for your target audience, most of whom will have slower connections than those common among developers. The Flash Bandwidth Profiler is useful for evaluating the download time for a simple SWF file when simulated in Test Movie mode. You can access it by using Control?Test Movie to enter Test Movie mode and then choosing View?Bandwidth Profiler to open the Bandwidth Profiler window. However, the Bandwidth Profiler assumes an ideal connection, so choose a target connection speed somewhat slower than the ideal speed of your lowest-bandwidth user. For example, choose 28.8 Kbps instead of 56 Kbps to simulate a typical 56-Kbps modem.

Regardless, the Bandwidth Profiler included with Flash MX 2004 Version 7.0 is too simplistic for more advanced sites. Most commercially produced Flash sites consist of far more than a single SWF. Additional assets—such as secondary SWFs, images, MP3 files, video files, remote data, and text files (CSS, XML, etc.)—are routinely loaded at runtime. Prior to the Flash MX 2004 Version 7.0.1 update, the Bandwidth Profiler did not include these assets as part of its simulation, so it understated the download times.

The third-party WebSpeed Simulator (http://www.xat.com) is a useful alternative to the Bandwidth Profiler. It works by creating a local bandwidth-limited HTTP server and allows you to:

  • View the site loading in real time in a web browser on a simulated bandwidth-limited connection

  • View a timestamped browser cache, allowing you to review the order in which files were loaded (plus what is left available in the cache after your site has been visited)

The WebSpeed simulator is extremely easy to use. However, because the simulator works as an HTTP server, it cannot emulate secure servers.

Assuming you want to test a site from your local hard drive, click the application Setup icon in WebSpeed Simulator's toolbar to bring up the Setup Web Server dialog box, as shown in Figure 9-1, and specify the location of the site (i.e., the location of the folder containing your home page, such as index.html). You may also have to clear the browser cache depending on your browser settings. (For example, to clear the cache in Windows Internet Explorer, use Tools?Internet Options?General?Delete Temporary Internet Files.)

Figure 9-1. The Setup Web Server dialog box in WebSpeed Simulator

The Setup Web Server dialog box in WebSpeed Simulator

Then, click the Restrict icon and specify your simulated connection in the Restrict Web Server dialog box, as shown in Figure 9-2. You can also specify whether you want to preserve the browser cache (i.e., if you visit the same site twice, content already in the browser cache will load immediately).

Figure 9-2. The Restrict Web Server dialog box in WebSpeed Simulator

The Restrict Web Server dialog box in WebSpeed Simulator

Finally, click the Browse icon. The simulator directs the browser to the folder you specified during setup and acts as a server, limiting bandwidth as specified in the Restrict Web Server dialog box. As each item is loaded in the browser, the WebSpeed Simulator displays the time each file takes to load, the order of loading, and the filesize, as shown in Figure 9-3.

Figure 9-3. The WebSpeed Simulator results

The WebSpeed Simulator results

I keep WebSpeed Simulator running whenever I am working in Flash. It addresses the failings of the Bandwidth Profiler and provides a clean interface for easily testing at various bandwidths. Setup is trivial and you don't need to change your browser settings or your physical connection to test at different speeds, so it is very easy to integrate into your normal workflow. It can even evaluate sites that mix HTML and Flash, whereas the Flash Bandwidth Profiler works with SWF files only. Experience with using WebSpeed Simulator confirms it is an accurate simulation—the times predicted by the simulator are very similar to the actual content download times.

Final Thoughts

Although WebSpeed Simulator isn't free (it costs $99, but a 30-day trial is available), it's by far the easiest environment I've found for testing bandwidth requirements on any web site design, particularly for multifile Flash sites.

Keeping it handy during the course of development will prevent surprises. The ease with which it can be set up allows you to even, say, demo a site under simulated web conditions to a client using your laptop. This comes in handy when helping your client understand bandwidth considerations when making design decisions. It even works for Flash applications that load a lot of dynamic data, so it is invaluable to RIA developers and motion graphics designers alike.



Hide Low-Quality Settings

Copyright © 2004 O'Reilly Media, Inc. All Rights Reserved.
Flash Hacks: 100 Industrial-Stength Tips & Tools
By Sham Bhangal
June 2004
ISBN: 0-596-00645-4
http://www.oreilly.com/catalog/flashhks/index.html
Available from booksellers or direct from O'Reilly Media, www.oreilly.com.

Cover image
This content is excerpted from the above-named O'Reilly publication, with permission, by agreement with ActionScript.org.

Increase performance and maintain visual appearance by hiding the effects of a reduction in rendering quality.

There is an inherent trade-off between rendering quality and performance, and Flash offers several rendering modes. Understanding the issues at hand can help you to both make the appropriate choice and work around some of the limitations of the built-in rendering options.

The Flash rendering engine optionally uses antialiasing to smooth out vector edges and increase apparent quality by hiding aliasing errors (a.k.a. "staircasing" or "jaggies"). Antialiasing tends to hide sharp edges between contrasting areas by blending in pixels of intervening shades. In Figure 9-4, the curve on the left exhibits aliasing errors that show up as jagged edges caused by our pixels being too large to faithfully reproduce the curve. The one on the right is antialiased and looks smoother.

Figure 9-4. An aliased curve (left) and an antialiased curve (right)

An aliased curve (left) and an antialiased curve (right)

Note that antialiasing doesn't fix aliasing errors but rather hides them from the human eye by using similar colors to smooth the transition between adjacent, contrasting colors.

Antialiasing can be processor-intensive, and you may prefer to turn it off to get the benefit of increased performance.

You can turn antialiasing off globally (i.e., for all content seen in the Flash Player) with the following line:

_quality = "LOW";

You can also set the rendering quality to Low under File?Publish Settings?HTML?Quality. Note that the MovieClip._quality, Button._quality, and TextField._quality properties are merely synonyms for the global _quality property and therefore affect antialiasing globally. Quality cannot be set on a per-instance basis.

In addition to "LOW", you can set the _quality property to "AUTOLOW", "MEDIUM", "AUTOHIGH", "HIGH", or "BEST". In the higher quality settings, text, bitmaps, and vectors are antialiased. At the lowest quality setting, none are antialiased. The exact details of each level of quality can be found in the Help panel (Help?Help or F1) if you search for "_quality." In practical terms, use the highest quality that your content and target audience's machines allow. This generally means using "BEST" for largely static sites, "HIGH" or "MEDIUM" for most general content, and "LOW" where speed is a priority, such as in games.

You can also make Flash selectively turn antialiasing off via the Auto High and Auto Low quality settings. At those settings, the Flash Player automatically switches between antialiased and aliased rendering depending on the playback performance of the machine on which it is running. The Auto High setting starts with antialiasing on and turns it off if overall performance suffers (i.e., the frame rate slows down unacceptably), whereas the Auto Low setting starts with antialiasing off but turns it on if the target frame rate is achieved.

The Auto quality settings are not often used because the change from high to low quality is usually very obvious and disconcerting to the user. For best performance, the trick is to permanently set the quality to Low and then try to hide, as far as possible, the resulting low-quality rendering.

Use Noncontrasting Colors

Given that antialiasing is needed most when contrasting colors are adjacent to each other, one solution is to use noncontrasting colors to begin with. In Figure 9-5, the aliased line (on the left) should look less blocky than in Figure 9-4 because the black curve is similar in color to the gray background (the difference is more apparent on screen than in print). Of course, by definition, reducing the contrast makes the curve harder to distinguish from the background, so don't make the background too similar in color. If necessary, you can improve contrast by making the line thicker or darker.

Figure 9-5. Aliased (left) and antialiased (right) curves on a low-contrast background

Aliased (left) and antialiased (right) curves on a low-contrast background

When attempting to improve apparent quality by using noncontrasting colors, you should avoid some color combinations:

  • Black on white and black on yellow are the two most contrasting color combinations and should be avoided. Black and yellow is the most contrasting (which is why bees and hornets have black and yellow stripes as a warning coloration and why the phone company chose it for the yellow pages).

  • The human eye is most sensitive to green and can differentiate between close shades of green better than shades of red or blue. Other things being equal, avoid greens when using low quality settings.

  • There are several types of color blindness (and infinite variations along the spectrum), but the most common deficiency is an inability to perceive the difference between red and green. So avoid red-on-green or green-on-red color schemes. For more information on color schemes appropriate for color-blind users, see Toledo-Bend (http://www.toledo-bend.com/colorblind ), which discusses various color perception deficiencies.

Use Horizontal/Vertical and Fast-Moving Shapes

Other ways to hide low-quality (aliased) vectors include making sure your Flash movie assets, whenever possible, use rectangular fills, are moving quickly, or consist of horizontal and vertical lines only.

Horizontal and vertical lines, including the edges of rectangles, do not need antialiasing, and you simply can't see the aliasing on something that is moving quickly. The latter point can be used in Flash video games. When you are at the title screen or game instructions, a quality setting of High or Best can be used without compromising performance, but once you get into the game, fast graphics become important, so you will be more likely to switch to Low quality. Additionally, if your game is moving fast enough (and you have only horizontal- and vertical-shaped static graphics, such as the Pacman maze), the user may not even notice the switch in quality.

Some caveats, however: if designing output for video, avoid 1-pixel horizontal lines. Because video for broadcast TV is interlaced, lines should be at least 2 pixels thick to avoid flickering. Even for online video playback, certain compression schemes have trouble with extremely thin lines. So perform tests before committing to your final design.

Also, even perfectly horizontal and vertical edges can benefit from aliasing to soften their edges. This is especially true for vibrant colors (particularly the primary colors when shown on a white background), which appear to bleed when given a hard edge.

Use Pixel Fonts

Turning on text antialiasing (which occurs to varying degrees when using any quality setting except Low), especially for large amounts of text or moving text, can really tax the processor. On the other hand, using aliased text in fonts designed for printing can result in poor onscreen appearance. Conversely, antialiasing can make text harder to read at small point sizes (below, say, 8-point text, depending on the font).

If using a lot of text or small text, you should use pixel fonts, which are fonts designed for onscreen that look better without antialiasing, as shown in Figure 9-6.

Figure 9-6. Pixel fonts and small fonts look better without antialiasing

Pixel fonts and small fonts look better without antialiasing

For general information on pixel fonts, see the Web Page Design for Designers site's pixel font FAQ (http://www.wpdfd.com/pffaq.htm) and primer on pixel font typography (http://www.wpdfd.com/wpdtypo3a.htm).

There are a number of free resources dedicated to Flash-specific pixel fonts, including:

  • miniml (http://www.miniml.com) offers miniml fonts, a collection of vector-based pixel fonts.

  • Fonts for Flash (http://www.freepixelfonts.com/faqs.html) has a Flash-specific FAQ on pixel fonts.

  • Best Flash (http://www.bestflashanimationsite.com/pixel-fonts) offers links to Flash-related pixel font resources.

Final Thoughts

As you will realize when trying to create complex animations with Flash, there are limits to how fast Flash can render vectors. Reducing the image quality by turning off antialiasing (using a quality setting of Low) is one of the quickest ways to improve performance, but it seriously affects those crisp vector edges for which Flash is famous. As we have seen here, you have several options to minimize or hide the effects of this loss of quality. You might even incorporate the aliasing into your design to give it a retro feel. Of course, changing the rendering quality isn't your only option. The remaining hacks in this chapter present other ways to optimize performance.


Optimize Graphics for Performance

Copyright © 2004 O'Reilly Media, Inc. All Rights Reserved.
Flash Hacks: 100 Industrial-Stength Tips & Tools
By Sham Bhangal
June 2004
ISBN: 0-596-00645-4
http://www.oreilly.com/catalog/flashhks/index.html
Available from booksellers or direct from O'Reilly Media, www.oreilly.com.

Cover image
This content is excerpted from the above-named O'Reilly publication, with permission, by agreement with ActionScript.org.

Graphics can be bandwidth hogs. Optimize graphics for large dividends in overall performance.

The Flash graphic-rendering engine is designed to minimize the filesize of your content by optimizing the drawing of vector graphics instead of bitmaps. Therefore, performance can be a problem when you want to move complex graphics around quickly. Once a graphic is downloaded, the biggest bottleneck is usually the time it takes Flash to render it to the Stage (by comparison, the time to execute most ActionScript is usually trivial). The larger the area of the Stage being updated per frame, the slower the performance. So large, low-bandwidth vector graphics can still take time to render.

The following tips are based on my experience and that of other designers in creating fast Flash sites.

Design with Speed in Mind

It sounds obvious, but most developers forget Flash can't do everything at once. Here are some potential performance killers:

Loading content

Streaming in an animation at the same time as playing it will reduce the maximum achievable frame rate compared with loading the content first and then playing it after it is fully loaded. It is often better to have a preloader screen than try to play the animation before it is fully loaded (in which case you have to wait for the rest to download as the animation plays).

Playing MP3 files, especially long ones

MP3 files are decompressed during playback, which requires lots of processor time. Although Flash can handle one or two short sounds easily, if you have long sounds and multiple sound channels, expect animation to slow down.

Updating text fields

Updating a text field's content every frame is one of the biggest performance-sapping actions that can be easily avoided. Instead, you should change text field values only when their content actually changes or at the slowest rate you can get away with. For example, if you are updating a timer that displays seconds, you don't need to update it at a frame rate of 30 fps. Instead, record the old value and reassign the value of the text field only when the new value is different from the previous value.

Using Flash MX 2004 v2 components

If you're using components, then you're usually creating an application with minimal animation, so animation performance is not the limiting factor. Flash MX 2004 v2 components are real performance killers. Not only are they bandwidth-heavy, but using more than a few onscreen slows runtime performance. If you want to run fast animations, use Flash MX's v1 components [Hack #73], use your own custom components, or create simplified user interfaces that don't require components.

Create and Test Optimized Graphics

Bitmaps can be larger than vectors to download, but the pixels required to render a bitmap don't need to be calculated at runtime. So once they are downloaded, they can be rendered relatively quickly. Vectors have the opposite characteristics. Because they are stored as a mathematical representation, vectors are very compact. However, unlike bitmaps, the pixels required to render the vector content must be calculated at runtime. You can sometimes improve performance by using bitmaps instead of vectors [Hack #72], but more often, you need to create vector graphics that Flash finds easier to draw.

The following tips will help you create vector graphics that render quickly:

  • Avoid using transparency (alpha). Flash must check all pixels underneath a transparent shape, which slows rendering down considerably. To hide a clip, set its _visible property to false rather than setting the _alpha property to 0. That is, graphics render fastest when their _alpha is set to 100. Setting the movie clip's timeline to an empty keyframe (so that the movie clip has no content to show) is usually an even faster option. Sometimes Flash still tries to render invisible clips; move the clip off stage by setting its _x and _y properties to, say, (-1000, -1000), in addition to setting the _visible property to false, so Flash doesn't try to draw it at all.

  • Avoid using vectors with gradient fills. Consider using a bitmapped gradient instead.

  • Flash's drawing performance is tied to how many points are drawn per frame. Always optimize shapes after you have drawn them with the Modify?Shape submenu, then select either Smooth, Straighten, or Optimize (depending on your graphic) to reduce the number of points required to draw it. Changing strokes to hairlines (or not using strokes at all) can also significantly reduce the number of points needed. You can view the number of points contained in a stroke by clicking on it with the Subselection tool, and you can see the number of points in a shape by clicking on any of its edges.

  • Flash's drawing performance is also tied to the number of pixels that have to change per frame, so avoid large changes. Make your animated content as small as you can get away with; for example, reducing the size of a graphic by 10% in each dimension reduces the area by 19%. The savings really add up when using multiple copies of the symbol, such as for a Space Invaders game.

  • Use hollow (unfilled) shapes or other shapes that reduce the total number of pixels drawn if you can.

Tip

Note that, unless you are using alpha effects, pixels that do not change between frames don't significantly affect performance.

Final Thoughts

Many aspects of a Flash movie contribute to its ultimate performance. Optimizing graphics is one of the areas likely to yield the biggest changes. Graphics can be optimized at any point in development; however, the earlier you optimize them in your design cycle, the greater the benefit you're likely to achieve. If you wait until the last minute, you won't have time to optimize everything, and certain design decisions that could have been adjusted earlier, such as whether to use transparency, will be much harder to change. The moral is to optimize early and optimize often.

Third-party vector optimization programs, such as Optimaze (http://www.vecta3d.com), reduce filesizes up to 60% and allow for faster rendering because the optimized vector calculations will be simpler.



Benchmark Runtime Performance

Copyright © 2004 O'Reilly Media, Inc. All Rights Reserved.
Flash Hacks: 100 Industrial-Stength Tips & Tools
By Sham Bhangal
June 2004
ISBN: 0-596-00645-4
http://www.oreilly.com/catalog/flashhks/index.html
Available from booksellers or direct from O'Reilly Media, www.oreilly.com.

Cover image
This content is excerpted from the above-named O'Reilly publication, with permission, by agreement with ActionScript.org.

The Flash Bandwidth Profiler and third-party tools provide estimates of a Flash project's download time. Benchmark runtime performance to optimize playback as well.

The Flash Bandwidth Profiler and the third-party WebSpeed Simulator [Hack #66] calculate estimated download times, but they don't address runtime performance. Whereas the former varies with connection speed, the latter depends on the processing power of the playback machine. The user's overall experience is determined by a combination of the download times and runtime performance. It makes sense to make intelligent decisions about the trade-off between the two, as when substituting bitmaps for vectors [Hack #72] .

Runtime performance is inherently judged relative to the target frame rate, which is chosen by the Flash developer. If Flash can draw everything required by the time it is supposed to display the next frame, then it doesn't necessarily matter whether Flash had time to spare. However, this standard can overlook problems that might appear if you decide to increase the frame rate. You'd rather know which graphics are taking the longest to animate and which ActionScript is taking the longest to execute, so you can optimize each operation to reserve processor time for other things, like audio playback.

I use the following code to benchmark the effects of optimization. It uses a 1-millisecond interval, created with setInterval( ) [Hack #27], rather than an onEnterFrame event, which is tied to the frame rate. This forces Flash to redraw the screen as fast as it can, but it won't run every millisecond (perhaps every three milliseconds) due to performance limitations.

[as]function animate(target) {
// Animation script to move target clip across the Stage.
target._x = (target._x + 1) % 400;
count++;
updateAfterEvent( );
}
function controller( ) {
clearInterval(animater);
// Display average redraw time (in ms).
trace(clip[clipPointer]+ " " + 20000/count);
// Animate next clip for 20 seconds (if there
// is another clip still to test).
clipPointer++;
if (clipPointer < clip.length) {
count = 0;
animater = setInterval(animate, 1, clip[clipPointer]);
} else {
// If there is no other clip to test, stop.
clearInterval(timer);
}
}
// Setup
var clip:Array = new Array( );
var clipPointer:Number = 0;
var count:Number = 0;
clip[0] = clip01;
clip[1] = clip02;
clip[2] = clip03;
var animater:Number = setInterval(animate, 1, clip[clipPointer]);
var timer:Number = setInterval(controller, 20000);[/as]

In the preceding code, if clip01, clip02, and clip03 are three instances of a movie clip (for example, three versions of the same shape with different levels of curve optimization applied via the Modify?Shape submenu), the code will animate each instance as fast as it can for 20 seconds. It returns the average time to redraw the movie clip in milliseconds, and this can be used to make a comparison between the clips.

Tip

The preceding code is designed to benchmark reasonably complex shapes. It doesn't account for the time taken to run the code, but it does give you an idea of the relative rendering times.

By using such a testing scheme, you can get impartial data with regard to system performance. This is much more reliable than asking beta testers whether an animation was fast or slow. You can accumulate data on a variety of machines, especially the low end of your target machines, to evaluate the appropriate trade-offs between appearance and performance. You'll often find that minor differences in visual appearance (hardly apparent to users) result in measurable improvements in runtime performance.

Final Thoughts

The benchmark code offers a more realistic evaluation of performance than relying on the general optimization rules alone. It also helps you evaluate the trade-offs between techniques that conserve or consume processor power. For example, a complex shape containing many points may animate faster than a larger, simple circle. Furthermore, a solid shape moving in front of a bitmap may cause a bigger performance hit than a movie clip with transparency that is moving over a much simpler background.

Using code to benchmark your optimizations gives you the best idea of what has the most impact on performance for your particular animation. This type of benchmarking is best for comparing techniques to see which is relatively faster, not to see how fast an animation or application runs in real life [Hack #70], which depends heavily on the end user's computer and processing load.



Adjust the Animation Complexity Dynamically

Copyright © 2004 O'Reilly Media, Inc. All Rights Reserved.
Flash Hacks: 100 Industrial-Stength Tips & Tools
By Sham Bhangal
June 2004
ISBN: 0-596-00645-4
http://www.oreilly.com/catalog/flashhks/index.html
Available from booksellers or direct from O'Reilly Media, www.oreilly.com.

Cover image
This content is excerpted from the above-named O'Reilly publication, with permission, by agreement with ActionScript.org.

Measure the Flash Player's runtime performance in order to adjust the complexity of an effect or animation dynamically to run optimally on both low-end and high-end machines.

In the preceding hacks, we've seen ways to improve performance, regardless of the playback system, by optimizing a Flash movie's assets at authoring time. Optimization of that sort is essentially a lowest common denominator affair. This hack addresses the need to maximize animation and other effects for faster machines without creating a movie that bogs down on slower machines.

Although Flash Player 7 performs better than previous versions, it is still not a speed demon. The underlying goal of Flash is to optimize filesize (i.e., reduce download time) rather than provide breathtaking performance. Although we can improve performance by lowering the render quality [Hack #67], in many cases, turning off antialiasing can result in an unacceptably poor appearance for your site.

A better way to improve performance is to adjust the complexity (i.e., how much is happening per frame) of a graphical effect rather than its quality or frame rate. This approach can yield better results over a wider range of user systems with varying processing power than a one-size-fits-all optimization.

Adjusting the complexity is often an iterative process based on experimentation (with time it will become second nature and require fewer iterations):

  • Start with a target frame rate, such as 18 fps.

  • Measure the achieved frame rate, as covered shortly.

  • If the desired frame rate is not achievable on the test machine, reduce the complexity of the effect.

  • If the effect is rendered quickly enough, you have the leeway to increase the complexity of the effect.

Now that you understand the basics of the approach, let's automate it so that Flash decides dynamically whether to reduce or increase the complexity of the animation. This approach protects against sluggish performance on slower machines and (when done well) enhances the effect on faster machines.

We do not intend to change the frame rate, but rather change the complexity of the effect, in such a way that it always completes just before the next frame starts.

Calculate the Achieved Frame Rate

The following code creates an empty movie clip called perfMon (performance monitor) and attaches an onEnterFrame( ) event handler to it. This event handler calculates the average frame duration (in milliseconds) using the last two timer measurements, creating a rolling average. This rolling average, time, is compared against the expected duration, FRAME_DUR, and a Boolean flag, slow, is set to true or false based on whether the Flash Player is achieving the target frame rate.

[as]function performanceMonitor( ) {
this.createEmptyMovieClip("perfMon", 10000);
perfMon.onEnterFrame = function( ) {
time = (getTimer( ) - lastTime) / 2;
lastTime = getTimer( );
// Set slow to a Boolean based on whether the
// elapsed time exceeds the allowed frame duration
slow = time > FRAME_DUR;
};
}
// Set FRAME_RATE to match the movie's target frame rate
var FRAME_RATE:Number = 18;
var FRAME_DUR:Number = (1 / FRAME_RATE) * 1000;
var time:Number = 0;
var lastTime:Number = getTimer( );
performanceMonitor( );[/as]

A slow value of false indicates that we can make the Flash Player do more without compromising performance because it is completing all its tasks before the start of the next frame. Ideally, we would want the Flash Player to finish all tasks for the current frame just as the next frame starts. We know this is happening when our rolling average, time, is equal to the expected frame duration, FRAME_DUR.

Adjust the Complexity Based on Performance

Let's see how to make Flash increase or decrease the animation's complexity based on the performance monitor's calculation. One simple approach is to draw more or fewer movie clips depending on the value of our slow flag. For the sake of example, let's use a star field particle effect [Hack #33] . The following code assumes a default Stage size of 550 400 pixels, with a dark background color. The effect works best with a frame rate of 18-24 fps. To set the background color and frame rate, select Modify?Document and adjust the properties as desired. The following code assumes a frame rate of 24 fps, and if you choose any other rate, you will need to change the following line to reflect this:

[as]var FRAME_RATE:Number = 24;[/as]

Note that you have to do this manually because there is no property or method in Flash that returns the movie's target frame rate (strange but true!).

We've modified the starfield( ) function from [Hack #33] to draw a single star at a time. Instead of setting the slow flag when the animation is running slowly, we use an if statement to adjust the animation's complexity. If the animation is running quickly enough, it draws additional stars by calling starfield( ); otherwise, it deletes stars to maintain performance.

Again, it is important to realize that we are not varying the frame rate (and doing so would not be transparent to the rest of the SWF, in any case), but rather the complexity of the animation so that the time taken to render each frame in the animation is equal to all the available time per frame.

[as]function performanceMonitor( ) {
var perfMon:MovieClip = this.createEmptyMovieClip("perfMon", 10000);
perfMon.onEnterFrame = function( ) {
time = (getTimer( ) - lastTime) / 2;
if (time < (FRAME_DUR)) {
// Speed is okay
stars++;
starField( );
} else if (time > (FRAME_DUR + 10)) {
// Running too slowly
_root["star" + stars].removeMovieClip( );
stars--;
}
lastTime = getTimer( );
};
}
function mover( ) {
this._y += this.speed;
this._yscale += this.speed;
if (this._y > 275) {
this._y = 0;
this.speed = Math.ceil(Math.random( ) * 10);
this._yscale = 100;
}
}
function starField( ) {
var star:MovieClip = this.createEmptyMovieClip("star" + stars, stars);
star._rotation = Math.random( )*360;
star._x = 275;
star._y = 200;
var dot:MovieClip = star.createEmptyMovieClip("dot", 0);
dot.speed = Math.ceil(Math.random( ) * 10);
dot.lineStyle(1, 0xFFFFE0, 100);
dot.moveTo(0, 2);
dot.lineTo(0, 5);
dot.onEnterFrame = mover;
}
// Set FRAME_RATE to match the movie's target frame rate
var FRAME_RATE:Number = 24;
var FRAME_DUR:Number = (1 / FRAME_RATE) * 1000;
var time:Number = 0;
var lastTime:Number = 0;
var stars:Number = 0;
performanceMonitor( );[/as]

If you run the preceding code, you will see the star field build from no stars up to a maximum of several hundred stars, as shown in Figure 9-7. Use the Variables tab in the Debugger panel to view the variables on the main timeline, which displays results similar to those shown in Figure 9-7