Preloaders vs. as 3

Most people have heard about Preloaders now, but there are a lot of new issues with ActionScript 3.0.

A quick introduction to Preloaders

Preloaders have a variety of purposes. They show something good looking, they provide feedback for the loading, they give you a chance to show your name and set the mood. But most importantly, they make sure that the data is there in time when the user plays the movie. Now, what does a preloader do? To answer this question, we have to ask ourselves “What if there is no preloader?”, The answer is that the player will try to do its own loading; it will load the content and pause playback if it runs out of loaded data. This is clearly not a good experience for the user since the sudden pause will ruin the experience and annoy the user.

A preloader solves this problem by loading all the data before playback, guaranteeing that the data will be available when used. However, a preloader in Flash does not actually load the data; the player is already doing that. What a preloader does do is to stop the playback and wait for the load to complete. It usually also provides an indication on how the loading is progressing.

The simple preloader in flash

A simple preloader in flash stops the main timeline and waits for the movie to finish loading. One simply adds the preloader to the first frame and that is it. But what is really going on? The preloader adds two listeners to the LoaderInfo object for the main timeline, so that it knows how the loading goes and when it is completed.

Now, an important question needs to be answered; why is the preloader in frame 1? The answer is that the preloader has to be before the rest of the content, since a SWF file loads sequentionaly, frame 1 is a good spot, and you can’t get any earlier in the file. This means that the preloader loads first of all, ensuring that it runs as soon as possible.

The load in first frame checkbox

Preloaders in flash are not free of pitfalls. The most common pitfall is that stuff other than the preloader is exported in frame 1. This means that there is more things than the preloader that needs to be loaded before the preloader can do its thing.

There are two variations on how this has happened. The oldest and most likely cause is that one or more symbols have been set to be exported in frame 1 by force. Before you uncheck this checkbox, you need to ask yourself, why does this option even exist?

Flash normally exports everything in the last possible frame, if something is not used until the fifth frame; it is exported in the fifth frame and so on. This is applied recursively as need. However, Flash can only do so much on its own. Scripts can create new instances at runtime of things that aren’t on any timeline. Flash can’t tell where it needs to export those symbols on its own. So by default, Flash exports them in the first frame, since there is absolutely no way the data is used before the first frame. The other option is to not export it at all, guaranteeing that it will not be available for scripting.

However, this does lead to that the data is placed in the first frame, the same frame as your preloader. This means that the load will take longer to load the first frame and that your preloader will not start immediately.

The flash player does not play a frame that has not completed loading. So, if not even the first frame have loaded, it has nothing to show at all, the famous white screen of death.

Now, there is a reason why the checkbox does exist, to let stuff that flash wouldn’t export otherwise be exported. So before unchecking this box, you need to take care of this issue that Flash was taking care of for you. This can be done by simply placing an instance of each symbol somewhere on the main timeline, this way Flash will have to export it there. You never need to actually play this frame; it just has to exist so that Flash has a reason to export the symbol. Of course, if you don’t uncheck the checkbox, it will still be exported in frame 1.

The document class

ActionScript 3 uses a new virtual machine and it has a new way of storing compiled code. It stores full classes in one SWF tag called DoABC. This is needed so that the engine can see the full class at once, it does not load parts of a class, it loads the full class in one go.

This has an impact for when you can use the class, it has to load fully first. When a class needs another class, both classes need to be loaded. This applies recursively as needed. The player also ensures that if a class bound to a symbol is loaded, so is the symbol. And the reverse, a symbol is not loaded until its class is loaded, if any.

In order to make more efficient SWF files, the compiler stores all the classes in one DoABC tag early in the file. The exact frame used can be set in the publishing settings. The classes are not considered loaded just because the DoABC tag has been loaded, the player does not let you use a class without it’s associated symbol.

Those that have read the section heading may know what the issue is now. The class for each timeline stores the framescripts in addition to the main content of the class. Since the class is required for a symbol to be instantiated, it has to be exported along with the rest of the symbol. The document class is no different. And since the main timeline itself is used at the very beginning of the movie, the document class has to be exported in the first frame.

However, this has a potentially unexpected result. Since the document class is loaded in the first frame, everything the document class uses has to be loaded in the first frame as well. And since the framescripts stored in the class commonly access things that have their own classes, the document class can be referencing classes for later symbols. Those symbols can be quite big.

Or to put it all into one sentence: everything ends up in frame 1 anyway. This is clearly a contradiction to what a preloader needs, to be alone in the first frame. The solution is not something that can be generalized into universal step by step instructions. You have to think about each relation for the document class and break the relations that are not needed. Only then will you be able to have proper preloading again.