Slow Flex Builder compile and refresh solution - Modules

For the past month I’ve been plagued with up to three minute compile times on Flex Builder 3 Beta 2. I’ve also been plagued with long several minute waits of “Refresing bin/”.

Last week I solved the issue for one of my projects and prevented it from happening to another.

Apparently embedding graphics causes a performance hit in compiling, refreshing directories, and even just before launching. So if you have a hundred or so of these:

<mx:Button icon=”@Embed(…)” />

You’ll be in a world of pain. The easiest solution is to move those embed calls into your style sheet and then compile your style sheet as a module.

Here’s how to make a style sheet module:

1) Create a new MXML module (file->new->flex->MXML module)
2) Add your stylesheet reference to that.

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Module xmlns:mx=”http://www.adobe.com/2006/mxml”
layout=”absolute” width=”0″ height=”0″
creationComplete=”trace(’iconsloaded’)”>
<mx:Style source=”style.css” />
</mx:Module>

3) Next, remove the reference to your style sheet from your main application.
4) Now, in your main MXML or AS file add some code to load your module.

protected var styleLoader:ModuleLoader;protected function init() : void{    styleLoader = new ModuleLoader();    styleLoader.addEventListener(ModuleEvent.READY, onModuleLoad );    styleLoader.addEventListener(ModuleEvent.ERROR, onModuleError );    styleLoader.url = “IconsModule.swf”;       styleLoader.loadModule();}protected function onModuleLoad( e:ModuleEvent ) : void{    maximize();    var mainApp:MainApplication = new MainApplication();    mainApp.percentHeight = 100;    mainApp.percentWidth = 100;    addChild(mainApp);   }

protected function onModuleError(e : ModuleEvent ) : void{    Alert.show(”Could not load module IconsModule.swf”,”Error”,Alert.OK );}

You can see there that I intialize my main application component after the module has loaded. I didn’t have to do this in a Flex app, but in my AIR app that component wouldn’t get all of the new styles if created before the module was loaded.

Option 2

Sometimes, it wasn’t practical for me to put the embedded graphic in a stylesheet. In those cases I:

1) Made an interface listing all the embedded graphics

public interface MyGraphicsModule{// Bindable tags are there purely to suppress warnings,// these properties never change after startup.[Bindable(event="moduleChanged")] function get addIcon() : Class;…}

2) Make a class that implements that interface and extends ModuleBase, also embed the graphics in there.

public class MyGraphics extends ModuleBase implements TimeLinerGraphicsModule{[Embed(source="/art/toolbars/add.png")]protected var _addIcon:Class;public function get addIcon() : Class { return _addIcon; }

…}

NEVER import or otherwise use this class into your application. The goal is to keep it completely separate.

3) Create a module manager class

public class MyModules{[Bindable] public static var graphics:MyGraphicsModule;}

4) Set MyGraphics to be a module that gets built in your Project->Properties->Flex Modules settings.

5) Load your module somewhere at startup

public function loadModules() : void{graphicsModuleLoader = new ModuleLoader();graphicsModuleLoader.addEventListener(ModuleEvent.READY, onModuleLoaded );graphicsModuleLoader.addEventListener(ModuleEvent.ERROR, onModuleLoadFailure );graphicsModuleLoader.url = “MyGraphics.swf”;graphicsModuleLoader.loadModule();}

protected function onModuleLoaded( event:ModuleEvent ) : void{if( event.target == graphicsModuleLoader ){var o:Object = event.module.factory.create();MyModules.graphics = event.module.factory.create() as MyGraphicsModule;}}

6) Find the spot in your code that used that icon and replace it

So this:

[Embed(source="/art/icons/addIcon.png")]public var addIcon:Class;

Would become this:

public var addIcon:Class = MyModules.graphics.addIcon;

This all seems like a pretty tedius job to do, but I ended up writing a perl script to scour the source tree, find all the references, and replace them for me. Unfortunately I did that script as part of my day-job and can’t share it with everyone right now. I’ll ask for permission on Monday.

The end result was we went from a 3.5 minute wait from saving a code change to executing the application to a 20 second wait. Not too shabby considering the size of the codebase we have.

5 Responses to “Slow Flex Builder compile and refresh solution - Modules”


  1. 1 wenzi

    Great solution, well done Marc!

  2. 2 Tim

    Would creating a runtime CSS SWF accomplish the same thing as option 1? Why not use that method over creating a Module SWF?

  3. 3 Marc

    Hey, neat, look at that … runtime css swfs. Learn something new everyday. :)

    It certainly does look like it would cover option #1. We combined both options into a single module so we’ll probably just leave ours but that does seem like an easier solution.

  4. 4 Frankie Loscavio

    Also you may consider right clicking your flex project in Flex Builder 3 Beta 2 and choosing Properties > Flex Compiler. Then UNCHECK the box that says - “Copy non-embedded files to output directory”. from my experience in FlexBuilder 3 beta 2 this drastically increased my compile time. It’s just way too much to add every sub folder etc… when all you NEED is your embedded assets. I realize the module issue works but may also become tedious at times. Also Symbolic links to bin Directory works pretty good too for runtime assets. Anyways my 2 cents yo.

  5. 5 msdevweb

    Try to put this arguments on Project->Properties->Flex Compiler options panel.

    Where is: -locale en_US

    Write: -locale en_US incremental=true -keep=true

    It increases a little the building/compilling speed.

Leave a Reply