Thursday, August 18, 2005

Excluding AS2 Classes

Recently I have been looking at how to exclude classes from a swf as part of a strategy for constructing large multi-swf RIA where core classes are loaded in as a common shared library at run time and then individual forms are loaded on demand.

Flash 7 introduced the "exclude.xml" as a way to achieve this.

To exclude classes from compilation, create a specially named and formatted XML file and place it in the same directory as the FLA file. Name the XML file FLA_filename_exclude.xml, where FLA_filename is the name of your FLA file minus the extension. For example, if your FLA file is sellStocks.fla, the XML filename must be sellStocks_exclude.xml.

Place the following tags in the XML file:

<excludeAssets>
<asset name="className1"></asset>
<asset name="className2"></asset>
...
</excludeAssets>

The values you specify for the name attributes in the tags are the names of classes you want to exclude from the SWF file. For example, the following XML file excludes the mx.core.UIObject and mx.screens.Slide classes from the SWF file:

<excludeAssets>
<asset name="mx.core.UIObject"></asset>
<asset name="mx.screens.Slide"></asset>
</excludeAssets>

Ok so this does work but the problem is it does not work properly, there are still classes that get compiled into the swf.

I was pointed to this article by Darron Schall which did provide useful information.

However in one case after several hours work to rework a class so that it would be excluded I was pleased to see it worked and the class was excluded, however the swf footprint went up, I was wondering what was going on!
Well after poking around inside the swf using ASV I saw that though the target class was not there several other classes had now been included. These were unrelated to any changes I had been making.

So at this point I decided to go back to basics and try and look at some very simple cases to see what was really happening.

I created a swf with no assets but with some code that directly referenced half a dozen classes. Without the exclude file the swf was 54k, with the exclude file it was 159bytes, good so far!

I then created another swf with a particular component and with the exlude file it was 7k which was all made up of graphical elements in the component. Again, good so far.

So now what happens if I combine these two files?
Well at worst case the size should be simply the two individual file sizes added together, however if the two files shared some classes you might expect the total size might reduce.

So what did happen?

The resultant swf was 35k, why???
Using ASV I can see a whole bunch of additional classes were being included.

I cant see any logic to explain this behavior.

But thats not the end of the story, taking this 35k swf I added additional components and placed them on the stage.

Again logic says the swf size would stay the same or increase depending on the overlap of the classes needed but what happened was the swf decreased in size to 21k.

At this point I give up further testing, although using an exlude file does have a very significant effect and certainly becomes an essential part of the strategy for developing larger RIA's there is no way to predict its impact or plan the class structure to achieve the smallest size swf. Just to be clear, from my own testing on the average form I can achieve reduction in size ranging from 50% up to 80% using the exclude file but whatever reduction you do initially get there isn't anything you can do to tweek it to get the remaining classes excluded.

It would be nice to think that this might be sorted out in Flash8 but it has already been said that little has changed in Flash 8 related to actionscript and anyway MM's focus is moving away from Flash so I guess this might become a feature of Zom.

I should note in this respect that MTASC also supports an exclude file, though it uses a different format, from testing it was accurate and consistant in excluding files.

In fact we are currently using MTASC to build the core shared component library as it is able to achieve a significantly smaller footprint than the same built from the Flash IDE.

7 comments:

  1. have u considered defining and using intrinsic classes to reperesent your core classes at compile-time?.
    intrinsic classes just defines the classes and its methods and attributes which your modules can use at compile-time, and at runtime your core classes can kick in with the meaty bits from your shared library.

    ReplyDelete
  2. exclusion XML are not the only way to exclude classes from compile. I advise you to take a look at this article
    http://osflash.org/doku.php?id=using_a_swf_as_a_dll&DokuWiki=f352515534ab46fc2e5e32c2f64dc4fb
    Many interesting pieces of information.
    Well the fact is the exclusion xml does exclude ONLY the specified classes.
    Intrinsic classes are a way to do it, but yet you would have to regenerate the whole intrinsic package.
    In fact, the problem is managing dependencies. Steve Webster and I thought about the problem and we came with two solutions : his Asigen, and my Sexie, which are both open sources programs (hosted on OSFlash) which answer your needs.
    Hope I helped a bit

    ReplyDelete
  3. Rodney/Aggelos
    Thanks for the comments, I had thought about (but not tried) the intrinsic approach but rejected this for a number of reasons.
    Firstly there are a lot of classes that need to be converted to intrinsic (500+), secondly as you develop you will probably often need the none intrinsic versions to be able to test out certain things and I am not sure how you could easily switch between the two, thirdly this will need to be done by a number of developers with a variety of skill levels not just one so its really needs to be automated or simple.
    Also I am not convinved that the intrinisc approach even actually work in all situations, specifically as these include compiled components even if you have intrinsic classes Flash will use the non intrinisc version inside the compiled component when compiling your swf.
    It is a good suggestion and maybe I should explore it more but as said I do have reservations about its usefullness.

    ReplyDelete
  4. well then sexie generates the exclusion XML for MMC and the exclusion file for MTasc.
    As for Asigen, the arguments of the size of the package is not a good one imho. Moreover if you and your collaborators are working with FAME (which may be a good choice because of the cvs/svn plugin and son on) it is not THAT difficult to switch the source folder...
    Here is a workflow I see for you : You generate your intrinsic package (preferably with asigen which may be easier to use for intrinsic packages), submit it on a SVN or CVS, so that it is done once for all for everybody for a change.
    But well, I do say that if your need is the exclusion via a file or a XML, Sexie should do just fine.
    Before rejecting theses solutions give it a try. After all, afa I know, they are the only ones available

    ReplyDelete
  5. I've read somewhere and have also seen it in action that even if you exclude a class it wont exclude the classes the class imports or uses.
    I forget if you can get around this by using the full package name instead of an import. I haven't fully tested it. Might be worth a try.
    So if you have
    import classA
    import classB
    class myclass
    {
    public function myclass()
    {
    a = new classA
    b = new classB
    }
    }
    and your exclude only lists myclass you'll find classA and classB will still be compiled.
    The solution to this is to run a sniffer on your class files to generate a "class in use" list such that you can add it to the exclude.xml
    Why didn't they create an include list instead.

    ReplyDelete
  6. emile,
    True though in our case not an issue as we are excluding the entire XPComponents framework so we already know all the potential dependencies.

    ReplyDelete
  7. Aggelos,
    Thanks for the thoughts.
    Generating the exclusion files is not an issue for us.
    The exclusions are known and stable (its the entire XPComponent framework) and only takes a few mins to create.
    Asigen would be useful here sure, actually although I found the page for asigen on osflash I couldnt find a link to the download.
    SVN doesnt come into the picture as in this case were not talking about it being used in a shared enviroment, these will be various customers running there own projects in there own way but this is a side issue.
    Also regarding the intrinsics, just to be clear, AFAIK intrinsics wont work with compiled components in the IDE. The intrinsic is ignored and Flash picks up the code from the compiled component.

    ReplyDelete