Using _exclude.xml, the Good, the Bad, and the Wishlist

| 4 Comments | 1 TrackBack

It's no secret that you can exclude classes from your compiled .swf files. Thinking about the next version of Flash, I thought I'd sum up some of my thoughts about the exclude functionality.

Some background

If don't want to read the official documentation, I'll give an overview here. You can skip this section if you know what _exclude.xml files are.

Whenever you publish a .swf file, Flash assumes nothing. Everything that the .swf file needs to function properly is included during publishing. This is great for standalone applications using 1 .swf file, but if you're developing with a modular approach it has its drawbacks.

In a modular approach, generally you have a container with some core functionality. The module .swf files are loaded into that container then as needed. The advantage of this type of architecture is that, especially for larger applications, the user only downloads a specific piece of functionality when they need to use it rather than forcing a large download of the entire application. It's a load on demand world, after all.

So when you load module.swf into main.swf, chances are module.swf contains duplicate code. Not duplicate as in classes included multiple times in the same .swf, but rather duplicate as in classes included multiple times in the same overall application. Remember, Flash assumes module.swf will need to function on it's own so everything it needs is included, but in reality when you load it into main.swf the user will have the "core" stuff downloaded already that module.swf relies on. Obviously, having the core stuff included in module.swf is a waste of download time and bandwidth. The user has it available to them already, why make them download it again?

The solution, then, is to use _exclude.xml files. If I have a source file Module.fla, I can create a Module_exclude.xml file that will list out the classes that Flash should exclude from the module.swf file when published. This allows me to use strict typing and reference the classes via code, but save on filesize by not adding unnecessary bytes to the .swf. See the Flash Help for more details -- Using ActionScript in Flash -> Creating Custom Classes in ActionScript -> Excluding Classes

The Good

The concept of excluding classes is great. In an application that I'm currently building, one of the loaded .swf files weighed in at 59 KB. After configuring an _exclude.xml file and republishing, the file size dropped to a mere 12 KB. Yes, it can really make that much of a difference. Imagine an application that has 10s, even 100s, of external .swf files each comprising a separate piece of functionality. Using _exclude.xml can make a drastic difference in load times and bandwidth. In my case it saved 47 KB, for 1 module. Multiple that by 100 and you can see that it makes a difference...

The Bad

There are really three negative aspects of _exclude.xml. The first is maintainability. The second is even if you think it's working, it might not actually be. The third is, well... it doesn't always work.

  1. Maintainability

    This one is huge. The main drawback of _exclude.xml is that you have to specify each individual class file, line by line. If I have 150 classes that I want to exclude, then I need to have 150 separate entries in my _exclude.xml file. Not very fun trying to maintain a list of classes like that.

    If something changes and a new classes is added or removed, especially in the main.swf, then all of the _exclude.xml files need to get updated for the entire project. Again, not very fun. A good solid design phase should eliminate the addition and deletion of classes once the project is underway, but they still happen as requirements tend to continually change.

  2. Broken

    Encapsulation is a fundamental concept in OOP. If you use ClassA in your project, and ClassA uses ClassB to implement some functionality -- as a user of ClassA those details are hidden from you. That is, ClassB is encapsulated by ClassA and you shouldn't have to know, nor should you care, that ClassB is used to implement some of ClassA's functionality

    With _exclude.xml, this isn't the case. If you exclude ClassA, the ClassB that it relies on is not excluded. I believe this to be a fundamental flaw because it goes against the principle of encapsulation. When creating _exclude.xml, we're forced to care about how classes are implemented if we want to exclude ClassA and everything ClassA depends on. The better approach, in my opinion, is to preserve encapsulation and automatically exclude ClassA's dependent classes.

    Moreover, have you ever tried to track down dependant classes to exclude? It's not exactly easy.. if there's a large inheritance chain with multiple interfaces and such and lots of dependant classes, it can be almost impossible to get the exclude right by just looking through source code. Thankfully, ASV can be used to analyze module.swf and generate a list of classes available inside of it. I can't count how many times I've used ASV to help create _exclude.xml files, and I couldn't imagine trying to generate them by just analyzing the source code for the module. You can probably use Debug -> List Variables if you don't have ASV, but the tree view for classes in ASV is a much better option in my opinion.

  3. Still Broken

    Even if you manage to list all of the classes you want to exclude, chances are there will be a few classes that won't be excluded no matter what you do. The problem seems to be in the usage of static dependencies, but of course sometimes it works and sometimes it doesn't. In certain situations, classes with static dependencies aren't excluded, even if they are listed in _exclude.xml.

    For example.. in mx.styles.CSSStyleDeclaration, there is a line..

    static var CSSTextStylesDependency = CSSTextStyles;
    

    It looks innocent enough. CSSStyleDeclaration depoends on CSSTextStyles. By creating the static dependency variable we ensure that CSSTextStyles is included in the .swf if you inolude CSSStyleDeclaration anywhere in your project.

    However, the compiler doesn't seem to respect _exclude.xml in certain situations. If I say I don't want CSSTextStyles, I mean it.. but when it's listed in _exclude.xml, the compiler may ignore it and CSSTextStyles still finds a way to make it into the published .swf.

    If you try to reproduce what I just said with a simple example, you may notice that I appear to be wrong. However, trust me on this one... Create a new alert.fla and drag a v2 Alert component on the stage. Now, create an _exclude.xml for every single class in the .swf (or download alert_exclude.xml). When you publish the .swf, you can see that indeed all of the classes are removed. However, if you add a line of code to alert.fla:

    new mx.core.UIObject();
    

    Upon republishing, you'll note that mx.styles.CSSTextStyles hangs around event though it's listed clear as day in the alert_exclude.xml file. Maybe this is a bad example, but it shows that _exclude is still broken sometimes...

The Wishlist

I have 3 things I'd like to see implemented to address the maintainability and broken issues. The "still broken" issue is really a bug that should be fixed in the next IDE.

  1. Support for wildcards to exclude entire packages (including subpackages).

    Additionally, support for excluding dependent classes. If I want to exclude ClassA because it's in my main.swf, then everything ClassA depends on is *also* in my main.swf. So when I exclude ClassA from module.swf, please exclude everything it depends on as well and don't make me compile a list of dependant classes. I don't want to care how ClassA does what it does.. I just know I want it (and everything it uses internally) excluded, no ifs ands or buts.

  2. Some sort of authortime panel to automatically generate _exclude.xml files. I'd like to see a window that lists all of the classes that will be compiled in the current .swf file. A simple check box next to each one would allow me to exclude all of the classes I don't want. Why fiddle with an XML file and risk spelling something wrong when it's possible to have Flash help us build this?
  3. Building off of idea #2, this one might be a little too ambitious. While I think #2 is doable for the next release, this idea is what would be my ideal situation. I'd like to have a panel to load the .swf files that will be "present" in the overall application. Flash would then parse all of the .swf files and automatically generate _exclude.xml for me, without me having to check anything off. Basically a "if it's in any of these .swf files that I'm pointing you to, don't include it in the current .swf file when I publish." That would be ideal, at least to me.

Also, while we're on the topic, if you make use of _exclude.xml, or plan to in the future, check out the enable/disable _exclude.xml files extension to allow quick testing in the Flash IDE.

An alternative approach that will remove the tediousness of configuring these files yourself is Ariaware Optimizer, if you have the money for it. Note that the still broken issue does not apply to Optimzer, as Optmizer will extract all of the classes from the .swf file after it has been published by Flash.

And of course, the bug report / wish form is located at: http://www.macromedia.com/go/wish. If you agree/disagree with me at all, or have any more suggestions, let your voice be heard by submitting that form on Macromedia's site.

1 TrackBack

TrackBack URL: http://www.darronschall.com/mt/mt-tb.cgi/29

links for 2005-04-07 from The Organization on April 7, 2005 4:17 AM

IFBIN.COM - Great Software Examples (tags: resource flash examples code) swfmill A tool to create swf's from XML. works nice with MTASC, for creating swfs with images which you can then call with attachMovie from MTASC. (tags: flash xml... Read More

4 Comments

  • Never really tried the _exclude.xml method myself. What I did to cut down on the unneccesary/duplicate classes and reducing file size, was to use a shared library. It's the usual exporting of symbols (movieclips AS2.0 classes) to be shared across multiple swf. Unfortunately the classes have to be tied to a movieclip.

    It's a pity that the _exclude.xml method is such a hassle. It's a bit ridiculous to have to go and manually update each and every one of them.

     
  • Shared Libraries are a good way to share assets, but don't solve the problem of duplicate classes. In module.swf, if I use strict typing and reference mx.controls.Button in code somewhere, the Button class and all of the other classes it depends on is included in module.swf even if the actul Button component itself is imported for runtime sharing. The runtime sharing means get all the assets from the library, whereas the strict typing tells the compiler to include all of the class files.

    Combing Shared Libraries and _exclude seems to be the optimal solution for developing modular applications.

     
  • Oh yeah, this has been a gripe of mine since I first started playing with MX04. The fact that you are required to manually maintain an exclude file for each fla is a real pain.

    For me, the ideal solution would be a new command, importNoCompile (or some such thing), which tells the compiler to use import the specified class/package for error checking, but not to embed it into the swf.

     
  • What I do is quite simple, since there is no drawback to excluding classes that do not exist in the fla, I just have one exclude file that excludes everything.

    Then I wrote a JSFL command to publish my entire project, and before publishing each file it will copy the exclude file to the .fla's location and rename it, then publish the swf and delete the exclude file.

    All my classes are loaded once at the start of the application through a simple ClassLibrary.swf that includes all classes that are excluded elsewhere.

    This works easily enough for me, for the most part I don't exclude anything until it is time for a production release, so no messy exclude files to maintain. Just 2 files one that includes all and one that excludes all.

    Cheers,
    Jesse

     

Leave a comment

Flex.org - The Directory for Flex

Archives