//richinternet.blog

Viewing By Entry / Main
Thursday, September 13, 2007
Building monolithic Flex SWFs that still startup quickly

Monolithic Flex SWFs that still startup quickly? Doesn't that sound weird? Of course it does, but actually it works just fine. Thanks to the way the Flash Player downloads multi-frame SWF files it's possible to defer the loading of "heavy" parts of your Flex application making the startup time pretty fast - under the hood the Flash Player still streams in the remaining data (BWT, with "streaming" I'm not referring to live video streaming or anything video releated, there's an ongoing discussion about this somewhere else)

p>Although this behaviour is common knowledge to most Flash developers it's probably not to the typical Flex developer as all frame- and timeline-based business is properly hidden by the Flex framework. By default, a Flex application actually is a 2 frame SWF file. Frame 1 contains the bootstrapping code to create the Flex application and the preloader and frame 2 contains all classes of the application itself. After frame 1 is fully loaded the preloader is displayed as long as frame 2 is downloading (this results in the typical loading screen of a Flex application). Once the whole SWF is downloaded into the Flash Player, the Application class gets instantiated and displayed. Now, the typical situation is that this 2 frame SWF file gets bigger and bigger as your application gets more and more complex, thus the download size and therefore the application startup time increases. A typical refactoring is to partition the application into multiple smaller SWF files ("Modules") and load these Modules SWF files on demand at runtime - which introduces other issues like class linking optimizations etc.

Interestingly (and this is what this post is all about), it's possible to create Flex SWF files made up of more than these 2 frames. A nice side effect of this approach is that the SWF continues to download after the Application class has been created. This means the user can already interact with the Flex application while behind the curtain additional classes and assets gets pulled in. Or as noted in the Flex Developers Guide PDF on page 201: "The advantage to doing this is that the application starts faster than it would have if the assets had been included in the code, but does not require moving the assets to an external SWF file".

There's not too much documentation available on how to implement this in detail, however. The best available material on what really happens are this blog post by Roger Gonzalez (former Adobe employee who worked on the Flex compiler) and a Powerpoint presentation on Modules by Alex Harui (Adobe employee, Flex Team). On the last two pages of Alex' great presentation he mentions what would be possible if Modules (i.e. compilation units) would be added behind frame 2 in a Flex SWF file. Adding those additional frames to a SWF file can be achieved by using the mxmlc -frame compiler argument specifying a label/identifier for the frame and one or more classes that should be linked to the frame. At runtime this ensures that the class/classes do not get loaded before the previous frame is completely loaded - and tada: there you have your streaming Flex application :)

Here are the implementation details for a quick and dirty test case (Btw, while not necessary I added support for the Module API so this plays nicely with the mx.modules.ModuleManager class):

First, I created a simple plain Flex 2 Application. Next, a class called TestFactory which implements mx.core.IFlexModuleFactory was created. This class will later be used to create instances of a Module called Test. The TestFactory class also implements a public static function frame(value:Object):void which is needed later.

To link the TestFactory class onto an additional frame "outside" the default 2 frame section you'll have to add something like


-frame test TestFactory
to the mxmlc arguments (either in Flex Builder or on the command line). This creates the 3 frame SWF file.

At runtime when frame 3 is hit, the static frame() method on the TestFactory class is called (this is not documented anywhere) passing in an instance of the active SystemManager implementation. Inside this method you can then register the TestFactory on the ModuleManager:


ModuleManager.getModule("published://myTest").publish(new TestFactory());
Note: Although in the documentation it says to use an URL starting with publish:// it actually has to be published://. After the Module is published you can call

ModuleManager.getModule("published://myTest");
from withinh the application to get a reference to the TestFactory instance and call create() on it to create an instance of whatever is created by the factory class.

The neat thing is that this really gets streamed in while the SWF is downloading but after the creationComplete Event has been dispatched - in other words: your application is already up and running while in the background the SWF still streams in. I added another class on frame 4 which makes the SWF pretty heavy (the class on frame 4 simply embeds a 8 MB mp3 file) to see if the Application really gets started before everything is in place - and it worked exactly as expected. Very nice!

So in the end you may ask why to put everything into one monolithic SWF file at all when it seems much more elegant to load additional Modules as external SWF files. Of course, this may reduce total download size as it only loads a Module SWF when explicitely requested. This is especially true if your application is really consisting of many "mini apps" and chances are high that not every SWF needs to be loaded at all. If that's the case you should probably stay with Module SWFs. On the other hand, if you're application is not that partitioned and you just need better startup performance then the approach described above may be the perfect match.

Dirk.

Comments

Sweet! I can't wait to try this out. Cheers, Doug


This is very useful, I am currently in the situation where this could be very handy. Thanks for your insightful post.

Borek


Dirk,

Very cool post, and well written! .. you can also potentially start to look at ways of serializing information in localshared objects, to further gain in terms of performance...

As always a fan of your work! ;P

- Scott Barnes RIA Evangelist Microsoft.


Hi,

I have a flex application, and I need to compile it to run with Flash Player 7.

Someone can tell me if it's possible to do, if it's possible, how can I do that.

Regards.


This sounds fabulous but I'm a little confused. Any chance that you could publish the source for your code?

Thanks,

Mario




Sun Mon Tue Wed Thu Fri Sat
   1234
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30   

About this blog
www.richinternet.de

AIR (9)
Apollo (3)
BlazeDS (8)
Breeze (1)
Central (5)
ColdFusion (54)
Flash (57)
Flash Media Server (6)
Flex (160)
Flex Trace Panel (6)
FXUG (3)
J2Flex (4)
MAX (31)
Mobile (1)
mxmlc (1)
Other topics (42)
Plugins (5)
Video (4)

Copy Fully Qualified Classname Plugin for Flash Builder 4 (CFQCN)

Recent Flex Technotes
Recent ColdFusion Technotes
Recent Flash Technotes

http://www.flexperten.de
http://www.flexforum.de
http://www.flex.org
http://www.bloginblack.de
http://www.cflex.net
flexcoders mailing-list
flexcoders archive
more links...

Aggregated by fullasagoog.com
Aggregated by MXNA

Short Mode | Full Mode

Herrlich & Ramuschkat