Hack 68 Optimize Graphics for Performance

figs/beginner.gif figs/hack68.gif

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 ModifyShape 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.

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.