Internal Preloading in Flash MX 2004

One of the major limitations of setting up large dynamic applications in Flash MX 2004 is that most of your content (and hence most of your file size) gets dumped onto frame 1. This is especially true if you use a lot of Macromedia components.

There are a number of workarounds for this, including setting up an external file to handle pre-loading, but the best one I have found is to carefully move all of the content off of the first few frames, so that you can set up a proper preloader within the swf in the first two frames.

There are a number of steps to achieving this – I will walk through each of them, and you can download a simple demo at the end of this entry.

1) Set your publish settings to export AS2 classes export on a frame other than 1
By default, Flash compiles all of your AS2 classes onto the first frame of your SWF, so that they are ready to be used immediately when your SWF loads. Of course, this adds a lot of bulk to the first frame of your application. Luckily, we can override this behaviour.

In this example I’m going to set my classes to export on frame 5, so that I can set up a preloader in the first few frames. To accomplish this, simply open Publish Settings from the File menu, click on the Flash tab, then on the ActionScript 2.0 “Settings…” button. In the dialog that opens, type “5” into the “Export frame for classes” box.

2) Set up exported library items to load on a frame other than 1
As with classes, Flash defaults to exporting all library items that are set to “Export for ActionScript” to export on frame 1. In order to circumvent this, you must go through your entire library and find each item that is set to export for ActionScript. Then, for each of these items you must turn off “Export in first frame” and add an instance of the symbol to the frame you have decided to export your assets on (in this example, frame 5).

This is a very laborious process in larger projects, and for ongoing projects it can be very difficult to remember which symbols are set up properly for preloading, and which still need to be set up. To solve this problem, I developed a simple JSFL script which automates the entire process: It identifies symbols that haven’t been set up, turns off their “Export on first frame” property, and adds an instance of the symbols to whatever keyframe you specify. And because it only affects symbols that are not already set up, you don’t have to manage the process. One of our current projects has over 800 symbols in the main FLA, almost 200 of which are exported for ActionScript – as you can probably imagine, this JSFL has saved me a LOT of time.

You can download the JSFL, and find instructions for using it at the end of this entry.

3) Set up the preloader
Now all of your assets are loading on frame 5, so you have 4 frames to play with for preloading – this example only uses a single frame, but the timeline is easier to work with when it’s a little spaced out. The most important thing to remember is to not use embedded fonts, classes, or components in your preloader, otherwise you’re defeating the purpose.

For this example, I’m just going to set up a super simple preloader that just puts the percentage complete into a textfield (using _sans system font) on the stage. I could use the same percentage value to drive a progress bar or something fancier, but I want to make it easy. Here’s the code, placed on frame 2, together with a textfield called “loadStatus” – I use frame 2 so that Flash even has an opportunity to properly preload that frame before the playhead hits it:

onEnterFrame = function() {
var percentLoaded:Number = // wraps to next line:
Math.floor(getBytesLoaded()/getBytesTotal()*100);
if (percentLoaded == 100) {
// clean up:
delete(onEnterFrame);
// jump over our asset frame, and
// straight to our content frame:
gotoAndPlay(10);
} else {
loadStatus.text = "Loading: "+percentLoaded+"% done";
}
}
stop();

As you can see in the above code, once I hit 100% loaded, I skip over the frame I exported all of my assets to (otherwise I would get a really ugly screen with them all scattered everywhere – not to mention the CPU hit of instantiating them all at once), and straight to my frame with my application content. Also, don’t forget to delete your onEnterFrame function – you don’t want it to keep running in the background eating up resources.

The “Set up for preloading command”
As I mentioned above, I’ve scripted a simple, but very useful JSFL command that will automate prepping your symbols for preloading. To use it, follow these simple steps:


  1. download it by clicking here

  2. open it in Flash (using open… in the File menu, not by double-clicking it), and read the little disclaimer at the top

  3. open your FLA, and select the keyframe you want all of the symbols that are set to “Export for ActionScript” to be exported to

  4. Select “Run command…” from the command menu, and select the JSFL file


The command will search your library for any symbols that are set to export in the first frame. For each of these symbols, it will turn off “Export in first frame”, and create a new instance on the stage in the keyframe you selected. Simple!

NOTE: JSFL files have the potential to break things in your work – I would urge you to run them on copies of your files, rather than your originals in case something goes wrong.

You can download the demo mentioned in this entry by clicking here. Take a look at the bandwidth profiler when you test movie to see where the assets are being loaded.

[UPDATE JULY 16/2005]
There have been several comments on preloading audio clips. The approach we took was to create a single movie clip, and put each audio clip on a layer/frame. Note that audio will sometimes still play, despite being in a frame that’s never hit, so all the audio frames are changed to “stop” events.

You can download an updated jsfl here

Grant Skinner

The "g" in gskinner. Also the "skinner".

@gskinner

32 Comments

  1. What if you are doing Screens Based development?

  2. To the best of my knowledge, you’re forced to use an external preloader for a Screen or Form based application – one more reason I don’t use Forms.

    Cheers.

  3. Thanks for sharing this Grant. It’s good to see how others are leveraging jsfl in their workflow.

  4. i use almost the exact same setup for class export, etc. and made a very similar “no first frame” jsfl file (on my blog last week). I prefer to place the components on stage manually, as there may be items in the library I don’t want to include in the swf.

  5. You little beauty!!! Was using the container_mc method all this while, a la many others i believe, but nothing like every mc having its exclusive preloader.

  6. Handy. But to prevent the _sans type, if the preloader only uses numbers and the percent sign, I believe this wouldn’t amount to a large file size. This would enable you to have a bit more consistent design. Correct me if I’m wrong…

  7. Grant,

    Thank you so much for posting this. I’ve been struggling with this precice issue on a current project, and it has been driving me absolutely nuts.

    You note: “The most important thing to remember is to not use embedded fonts, classes, or components in your preloader, otherwise you’re defeating the purpose.”

    Is the an absolute rule? Before I had realized what issues were present, I wrote a Preloader Class (cute, right?), along with an App Logger Class (along the lines of Moock’s example, which sends messages out via LC for online debugging). I need to use the classes right away, in frame 1.

    While I’m happy to move the majority of classes over to frame 5, is it then impossible to have a few manually imported and available on frame 1? Did I paint myself into a corner by making preloading and debugging code into classes?

    With all the excitement about AS 2.0 and bringing class declaration to a more standard method, are we really supposed to be using timeline-based preloaders still? I’m happy to do so if there is no other option… I just feel a little frustrated.

    On a related note, I see odd behavior with some of the MM comps I use when I don’t export their classes in the first frame. In particular, button and combo box highlights don’t turn off correctly. Have you noticed this?

    Again, thank you for the thoughtful post. I’d be eternally grateful if you had any thoughts on these questions.

    John

  8. As it happens I was struggling with this as well. Sometimes its difficult to get around/find all the tweaks for getting that first frame down in size. Thanks a ton, I’ll be using this technique (and your nifty jsfl script) right away.

  9. Thanks Grant – What a time saver! Have just over 50 files that I was going to have to hand code to do this. This with the compileProject have gotten me out before 5:00 for the first time in months!!

  10. salut mai datimi nistie smekerii care le pot face in flash

  11. This worked great for my virtual tour. I also have a demo up that is not working. The output errors I am getting are as follow (I’ll just pot one and see what you thing):

    I have some script that targets going to another scene and playing. Here is an error –

    **Error** Symbol=welcomeVidSmall, layer=actions, frame=1274:Line 1: There is no class with the name ‘String’.

    _root.gotoAndPlay(“newRegScene”);

    It seems to me that I am missing a class. Should I go into the properties of the movie clip that is reporting the problem and make up a class or is there another alternative.

    Thanks!

  12. This works great and thanks for the JSFL. There is one problem.

    One cannot use classes where the code is not available to them when they are not exported on frame 1. DataSet, data.binding for example are not available at run-time when you include their SWC and then change their class export value.

    Any ideas for a work around or solution?

    Thanks!!

  13. hello … your web site is very wonderful for me …. i love flash animation …

  14. There seems to be a problem with certain components and this preload method.In particular the Menu and DataGrid.If I set the ClassPath other than frame 1 then these two components don’t seem to initialise properly,especially the Menu.If a simulated test is carried out then the DataGrid initialises and works fine but the Menu does’nt.Both have instances on the stage,so that is not the problem.It’s as if the Menu Class has’nt loaded properly prior to using the component.

    So you are forced to set the ClassPath to frame 1 in order to initialise certain components properly.

    Strangley though;when compiled for Flash Player 6 and ClassPath set to 3 everything is initialised but does’nt work properly.

    Anybody else encountered this problem?

    Robert

  15. Thanks Grant – What a time saver!

  16. Hey Grant,

    thanks for this.

    I just have 1 question. I notice that the JSFL does not do anything with embedded font symbols – is there anything that one can do to export these on a frame other than the first frame? I notice that even with that box unchecked they seem to get exported in the first frame.

    thanks again

  17. you rock man! this article has saved my butt!! million thanks.

  18. Thank you so much Grant. There were so many websites that I searched through that could not solve this problem. Your solution fixed it brilliantly!

  19. Thank a million, you saved me from haveing another white night.

    just a quick note, for sound files (in my case that where the weight of the movie clip was).

    i had to put each instance in a different frame.

    You are still my hero, got o get into this jsfl speil.

    Cheers, gideon

  20. I get an output screen full of errors like this:

    **Error** C:\Documents and Settings\rolivares\Configuración local\Datos de programa\Macromedia\Flash MX 2004\en\Configuration\Classes\mx\data\formatters\NumberFormatter.as: Line 18: The class ‘mx.data.binding.Formatter’ could not be loaded.

    {

    any ideas why this happens.

    im pretty sure i did exactly what is mentioned in this article.

    Any help is greatly appreciated

    Thank you

    Roric

  21. Ok I think i figured out whats happening.

    It´s loading all of the components ok (datagrid,comboboxes,etc..)except for the DataBindingClasses, no idea why.

    The DataBindingClasses are in the library and it is NOT exporting to the first frame.

    help please..

  22. Jonathan Decker July 15, 2005 at 10:36pm

    This is just what I’m already doing, I’m sad to hear there isn’t a better way. I’m wondering what it is you do with sound files that don’t have an intuitive visual representation. Do you just put them in otherwise empty movieclips on the stage, as I have done in the past? So ugly!

  23. I have added an updated JSFL that also handles the preloading of audio files (see the excerpt at the end of this post)

  24. As with da5id above, the biggest thing in my flash file are a couple fonts embedded in the library. Even following the advice above and using the JSFL, I can’t get these fonts to load in anything but the first frame. Anyone know of a way to get library fonts to load up somewhere other than the first frame? Thanks.

  25. I followed your procedure and got my preloader working(thanks for posting this article), but the problem is that my app uses the datagrid component and when I export classes to any frame other than 1, the column headers do not appear. I think this is a bug with the datagrid component.

    Any Ideas?

  26. the FLFile error is caused by not updating to Flash 7.2 (free upgrade on MM site @ http://www.macromedia.com/support/flash/downloads.html)

  27. This works great and thanks for the JSFL! Realy useful.

    Thank you!

  28. he FLFile error is caused by not updating to Flash 7.2 (free upgrade on MM site @ http://www.macromedia.com/support/flash/downloads.html)

  29. For Bruce, to correct your comment, the idea of the barcode began in 1932 and began implementation measures in 1948. There may not be an idea to implant people against their will, but what if that was the only means of accessing your accounts and other information.

  30. o correct your comment, the idea of the barcode began in 1932 and began implementation measures in 1948. There may not be an idea to implant people against their will, but what if that was the only means of accessing your accounts and other information.

Leave a Reply

Your email address will not be published. Required fields are marked *