Visualizing mxmlc’s link report

If you set mxmlc‘s link-report flag to true you get a file describing your application’s dependencies, including the size of those dependencies. Using some simple XSL and Ant you can get a more readable HTML version.

I realise that using “visualization” in the title of this article is a bit misleading, creating a HTML version of a report is hardly that. I hope to get some time to do something proper and useful, but it has to be another day, it’s late where I am, so the simplest possible will have to do for now, it something at least.

Generating a link report

In your Ant build file add an attribute to your mxmlc call like this:

<mxmlc ... link-report="link-report.xml">

The “…” is where your other attributes are, if you wondered.

Now, every time you run your Ant script a file called link-report.xml will be created.

The link report file format

The link report file is an XML file which contains a script node for each class that was compiled into the SWF file. The path to the file, modification date and size are given, as well as all prequisites (pre nodes, these are all parent classes) and dependencies (dep nodes, these are the types of instance variable etc.).

<script name=".../framework.swc(mx/controls/Alert)"
         mod="1162235852000"
        size="4789">
  <def id="mx.controls:Alert" />
  <pre id="mx.containers:Panel" />
  <dep id="String" />
  <dep id="mx.core:Application" />
  <dep id="mx.core:EdgeMetrics" />
  <dep id="mx.core:mx_internal" />
  <dep id="mx.controls.alertClasses:AlertForm" />
  <dep id="controls_properties" />
  <dep id="Math" />
  <dep id="AS3" />
  <dep id="mx.events:CloseEvent" />
  <dep id="mx.managers:PopUpManager" />
  <dep id="mx.resources:ResourceBundle" />
  <dep id="flash.display:Sprite" />
  <dep id="flash.system:ApplicationDomain" />
</script>

There are also some classes which are used but not compiled in, namely all classes in the flash packages, the ones that your application uses are found at the end of the link-report.xml file as children of the external-defs node. One conclusion we can make at this point is that the flash classes don’t affect the size of your SWF-file. They still show up as dependencies, however.

XSL + Ant

This data is perfect for transforming with XSL — and what’s even better is that it’s super simple to include the transformation in the build process, since Ant has built-in XSLT capabilities.

Just include this in your build.xml file after the mxmlc task (or better, make it its own target, and have a target which depends on both your compilation target and the link report generation target so that you can run them separately should you want to).

<target name="generate-link-report">
  <xslt
       in="link-report.xml"
      out="${build.home}/link-report.html"
    style="bin/link-report.xsl"
  />
</target>

Now all that is left is to write the XSL and were good to go.

The transformation

I’m not going to bore you with the details of the XSL, but let’s go through the important bits.

A brief look at the output

This is what I want the output to look like. The class name, qualified name and the size of the class in KB. The class name is linked to the source file (or the containing SWC, in case of framework classes). When hovering over the qualified name all the prequisites and dependencies should be shown, and those that don’t add to the size should be grayed out (in the sample below it works, but only in Safari, not sure why). The list should be sorted so that the largest class appears at the top, and there should be a sum of the sizes at the bottom.

link-report { width: 100%; border-collapse: collapse; }

link-report .size { text-align: right; }

link-report th { text-align: left; }

link-report td { vertical-align: top; }

link-report .hierarchy .dependencies, .hierarchy .prequisites { display: none; margin-top: 0.5em; padding-top: 0.5em; border-top: 1px solid #333333; }

link-report .hierarchy:hover .dependencies, .hierarchy:hover .prequisites { display: block; }

.external { color: #999999; }

The code

I recommend that you download the complete XSL before you read the explanations below: link-report.zip.

/

The template that matches the root generates a HTML wrapper, the table, table header and table footer.

Before the other templates get to transform the script nodes, they are sorted on their size attribute.

Also notice the expression that generates the sum of all sizes.

script

The template for script nodes generates each row in the table.

The path to the class is found by using the name attribute. If the class is inside a SWC the “inner path” is removed, since it isn’t useful in this context — the link can only point to the SWC, not inside it.

The qualified name of the class is found in the def node’s id attribute, and by removing everything before the “:” the local name can be retrieved.

To generate the prequisites and dependencies list, the control is handed over to the next template, but notice that the mode is set to “list”. This isn’t strictly necessary since we don’t match pre and dep nodes more than once. However, it’s not unthinkable, so I though that it was suitable.

dep|pre

A requirement that I set up was that external dependencies (classes that are not compiled in, and thus don’t affect the size of the application) should be grayed out. To do this, there is a test which sets a variable to “external” if the class is found amongst the children of the external-defs node.

I think that this test shows one of the elegant aspects of functional programming. Using only the simple expression /report/external-defs/ext[@id = $local-id] we can determine if there is a node named ext with an id attribute matching the current node’s id attribute. Doing this in an imperative language requires that we either loop over all the ext nodes, or create a lookup table, which in turn requires to loop over all the ext nodes. Unfortunately, in XSL there is a lot of bulk code which hides these elegancies.

Inline CSS

There is an inline CSS block, which serves two purposes, firstly to make the report not look hideous (although it manages that just barely), and secondly to hide the dependencies and prequisites, but also make them visible when you hover over a class name (which works in Safari, but not Firefox nor IE, if you know why, please write a comment below, I can’t be bothered to research this right now, sorry thanks to commenters Marc and Yoav it now works in all modern browsers).

The CSS should perhaps be an external file, but this way you don’t have to maintain more than one file. If you like you can modify the XSL to reference an external stylesheet.

Conclusion

Using my transformation you can get a readable overview of what makes your SWF as big as it is, and perhaps find some optimisation possibilities. If you already use Ant to build your application it will fit seamlessly into you existing build script, making it as simple as just to build your project to get an up to date report.

I hope to revisit this topic soon to show some more interesting aspects of the link report data, but you will have to do with this for now. If you have any suggestions please leave a comment.

If you missed the download link above, here is the XSL file again: link-report.zip

Update (March 5, 2007): I have fixed the link to the XSL, and also updated it to include how many references there are to a class (basically all dep and pre nodes with the same id as the class).

Update (June 19, 2008): The XSL file has been updated to output a proper doctype, which means that the hiding and showing of dependencies and prequisites now works in IE and FF. Thanks to Marc and Yoav who explained how to do it in their comments.

12 Responses to “Visualizing mxmlc’s link report”

  1. john Says:

    Hey,

    Awesome post! I can see how the info would be quite useful to us as we start tuning our apps.

    BTW, clicking on the “link-reportxsl.gz”, I get a 404.

  2. Ikezi Says:

    I can hover over your example and see the dependencies displayed, but in my own generated html, it isnt working (using firefox on winxp).

    You mentioned this feature only works on safari, but it would be helpful for me to be able to see the prequisites and dependencies; is there a way i can modify the generated html so that it displays them by default (not on hover) ?

    thanks in advance

  3. Theo Says:

    Yeah, you could remove some of the CSS in order for the dependencies and prequisites to be visible all the time. Just remove the :hover selectors.

  4. Greg Arakelian Says:

    I was just about to spend my morning doing exactly the same thing, i.e. writing some XSLT on link report, when I came across this post. Awesome! Thank you very much!

  5. Marc Says:

    Thanks for the xsl. In case you still care, FF and IE need the doctype for :hover. Add the following in the xsl:

  6. Theo Says:

    Your code got lost in WordPress’ filtering… try skipping the angle brackets, or e-mail me the code and I will add it to the post.

  7. Yoav Says:

    Marc got me curious – but he didn’t respond the question on the doctype. So I made small search and found out that all I need is to add this line to the resulting html:

    And that’s it – the hover works!

  8. Yoav Says:

    I’ll try again:

    !DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.01//EN” “http://www.w3.org/TR/html4/strict.dtd”

    (without the angle brackets)

  9. Theo Says:

    Thanks!

  10. Paige Davis Says:

    Hey!…I Googled for flash mx template, but found your page about …and have to say thanks. nice read.

  11. Max Says:

    Very useful information. Thanks!!

  12. Marcus Says:

    Found a little link reporter AIR app: http://www.kahunaburger.com/2008/03/08/air-link-report-visualizer/ ( I had to ‘open’ instead of ‘download then open’ the AIR package to get it to work :S )

Leave a Reply