A simple monkey patch to double Flex 4 instantiation performance

(That headline is a bit of hyperbole, but it was true for our project!)
UPDATE: According to Andrei (see comment below), this fix also halved the startup time of their app! Time to try to add some more keywords to this article in hopes that more folks will stop by and give this a shot: Flex 4 slow vs Flex 3. How to speed up Flex 4. Flex 4 performance. Also, Alex Harui recently posted on his blog about Flex 4 performance issues, and he mentions that their StyleProtoChain can be slow, and provides an alternate way of getting perf back. I haven’t tested his method though. If you do, I’d love to hear how it compares. And now on with the article…

We are in the process of upgrading our AIR app, You Need a Budget, to use Flex 4. We’re basically trying to change as little as possible, but we need to use Flex 4 for a new library of code we purchased. That means we’re still using our old MX controls, and we’re using the Halo theme. However, we quickly discovered a major performance bottleneck. Our app was taking at least twice as long to load as it did before. So, I loaded up the debugger and randomly started breaking into the code. Virtually every time I broke into the code, I was in the same darn function:
[code light="true"]StyleProtoChain::matchStyleDeclarations[/code]

For every component being instantiated, Flex was doing a linear search through all of our styles and asking each of them, “Do you apply to this component being instantiated?” We have a stylesheet with about 300 declarations in it, so that meant that Flex was making 300 queries per object instantiated. In short, it was slow.

So, I monkey-patched StyleProtoChain.as to make it cache these style lookups. No more linear searches! My fix is quick and dirty, so there are scenarios where the styles could get changed out from under the cache. Although it appears to work great for us, I can imagine lots of scenarios where it will break, so your mileage may vary. Still, my guess is that you’ll see a tremendous speed improvement. Our load times went down by more than half. Any time I can get performance increases like this with so little code, I want to share it with the world.

This is a monkey patch of Flex 4.1, so I don’t know how/if it will work for Flex 4.0 or 4.5. To find my changes look for the “//TB” comments or anything related to the matchUniversalStyleDeclarations function I added.

If you’ve never monkey patched Flex before, just drop this file into your project in an “mx/styles” folder. Do a full rebuild, and I believe you’ll be good to go. You might have to reference StyleProtoChain elsewhere in your project to guarantee it gets compiled in, but I don’t recall.

Tags: ,

5 Responses to “A simple monkey patch to double Flex 4 instantiation performance”

  1. Andrei Kouzmenkov April 30, 2011 at 9:29 pm #

    That’s a great finding, YNAB!!!

    Just tried the quick fix from the blog in our real application and got the promised result: application initialization reduced exactly by half.

    Also updated forum http://forums.adobe.com/message/3648094#3648094 and jira https://bugs.adobe.com/jira/browse/SDK-29451 with references to the blog.

    Finally some hope for migrating to SDK 4!

    THANKS!!!

    • Taytay April 30, 2011 at 10:44 pm #

      Awesome! I’m thrilled to hear it worked so well for you all too!

  2. Pedro June 8, 2011 at 2:42 am #

    Hi,

    How would this apply to 4.5? I get a bad include and doesn’t seem to improve that much if I remove the include.

    Also if I understood correctly you just drop it in your project folder right?

    Thanks in advance,
    P

    • Taytay June 8, 2011 at 3:55 am #

      Pedro, the file needs to be in the proper place in your project’s src folder. In this case, the file needs to be in the src/mx/styles folder. I also then recommend including the Version.as file that you can find in the Flex SDK source code folder. You would drop it into the src/mx/core folder. In our case, at our current version of the SDK, the file looks like this:

      import mx.core.mx_internal;

      /**
      * @private
      * Version string for this class.
      */
      mx_internal static const VERSION:String = “4.5.0.20967″;

      • Pedro June 8, 2011 at 4:15 am #

        Just did that, was coming over to remove my silly comment, apologies, also the patch works good with 4.5.

        Pre-coffee posts are always an issue.

Leave a Reply