LeichtgewichtLeichtgewicht

2010/04/30 – 13:38

Clean SWF’s in 10 steps

(for libraries, pedants and teams)

I am just in the midst of working at an application that takes a closer look at the swf’s we publish. While doing so I recognized that there are some things one might want to consider when you finish your work at a .swf that I saw many people not take care of.

1. Wait for the stage

If you compile a .swf then you easily think: Hey this is the Document Class and that means that the stage is immediately available. Wrong!

If there is another swf out in the net that loads this swf (maybe a future developer at your company) then the document class would not automatically be the stage root and will not have a stage object available in the constructor. Exceptions will raise and loading will not be possible.

Use addEventListener(Event.ADDED_TO_STAGE,…); in your document class to wait until it is added to the stage properly.

2. Draw the background

Having a solid background color is reasonable from a performance point of view (considering wmode is evil). Having your design built like that is good as well. But if someone loads your swf with Loader then it will appear transparent (actually it will draw a bit of the color). To have it  fixed, you might want to consider having a Shape in the background or drawing on your display class’s graphics object your background color instead of relying on a parent loader. Depending to the platform you aim to deploy to drawing of the background using a BitmapData may be faster than a Shape. I recommend to try it out.

3. The stage ain’t yours

You shouldn’t use Event.MOUSE_LEAVE to find out whether the mouse is on the your movie or not. That event indicates the absence of the mouse from the stage, which might be not yours alone. Same goes for keyboard events, focus, etc.

Stage.align & scaleMode are also not safe to simply use. A small check like if(stage.root==this) that can solve some headaches later on.

Libraries can help in teams to do this right depending on what you want to do with it.

4. Frame-rate optimizations

If you get all kinky about dynamic frame-rates you might want to think about it for a few seconds. If you have a container loading other swf’s and all of them try to manipulate the stage’s frame-rate and you will eventually run into strange bugs since all your swf’s try to access the same variable. Having a separate library for your frame-rate optimizations will for sure make this kind of things easier to handle.

5. The size may vary

You may take stage.stageWidth as your swf’s size if its loaded alone but if its used later on as a module it has no idea how big it should be. A small naming convention can help to still have it available as module.

class MySWF extends Sprite {
  private function init( e: Event ) {
     stage.addEventListener( Event.RESIZE, onStageResize );
  }

  public function setSize( width: Number, height: Number ): void {
    removeEventListener( Event.RESIZE, onStageResize );
    updateSize( width, height );
  }

  private function onStageResize ( e: Event = null ) {
    updateSize( stage.stageWidth, stage.stageHeight );
  }

  private function updateSize( width: Number, height: Number ): void {}
}

With this, an external loader can define the size – cool!

6. Be aware of loaderInfo.url specialties

If your .swf gets loaded in a foreign Security context, your loaderInfo.url will be strangely modified. If you really need to access the loaderInfo.url for some reason then be aware: it might look like this http://www.anotherdomain.com/[[IMPORT]]/yourdomain.com/yourcontent.swf – Jikes!

7. In swf version detection

Even if you use SWFObject to test for the player version. If the .swf is loaded by another .swf or if you .swf gets embedded in a different persons website/blog, your friend swfObject won’t help you out anymore. Since the security model changed in Flash Player 9 – you won’t be able to get that one easily “perfect” (AS3 code will not be called by players < 9 ) but FP 10 or 10.1 feature checking is easy and might be reasonable.

8. Write dispose methods & use them

This is one of the most difficult tasks. Assuming your swf is loaded by another container and later unloaded: The sprites will be removed but listeners to Sound objects (for example SAMPLE_DATA) will not be removed. Furthermore any circular references might persist. Especially listeners like stage.addEventListener(Event.RESIZE) are pretty persisting and cause memory leaks.

Writing a dispose method in your document class like root.addEventListener(Event.REMOVE_FROM_STAGE,dispose) that resolves all your circular references and removes all listeners is a good way to avoid that.

9. Remove debug code

Many, perhaps most of the webs swf’s still send trace messages. Beside the embarrassment of some statements and the possibility of telling a bit much about your structure they also consume CPU time. Using a logging framework avoids some of this problems. For more about logging see the best practices for logging by adobe.

Another thing: Having the swf compiled for debug (in flex build that reads: release build) not only stresses the file size of your swf it also slows it down quite significantly. The recommendations in the adobe documentation ain’t quite bad.

10. Use RSL’s (Flex user) or an application loader

(Just a optimization recommendation)
Writing code is simple stuff. With little time its easy for it to grow … and grow, until you finally reach a size close to the flex library. Anyways: If you have many common libraries that you use in your project think about packing some of your libraries in run-time-shared-libraries (if you use Flex) or use a home grown application loader. (perhaps I can get into that one deeper in a follow up post)

Resumé

This list might be far from final or complete but I think its a good start and contains a lot of things people don’t consider when they deploy a swf to the web. I hope you found it useful. In case you find something essential missing or disagree, please let me know.

Cheers
Martin.

Tags: , ,

Leave a Reply

Site informations

Martin Heidegger – Web Developerskype:mastakanedaxing:martin.heideggertwitter:leichtgewicht