Flex Data Binding Performance Pitfall

A friend of mine recently asked me to help him troubleshoot some performance problems with his Flex application. In his scenario he had a large list of data and wanted to filter the data such that each time the search string grew by a character the complex filter would only be run on the results of the previous filter. A very simple approach to this is just to keep a record in each item indicating if the item matched the filter for each search string. Even though the filter function will still run for each item, the complex part of the filter function could easily be isolated and only run for the subset of data which matched the previous filter. This may not be the best way to do this (I’m open to other suggestions) but it was simple. You can see the results of my first attempt here:

Demo 1 (Enter a few numbers in the search field and see how many items are being filtered and how long it takes.)
Source 1

Notice that in order to keep track of how many items are reaching the main part of the filter I increment a Bindable variable inside the filter function:

[Bindable] private var ffCount:Number = 0;
...
private function ff(item:Object):Boolean
{
...
    ffCount++;
...
}

Now since I’ve been programming in Flex for over four years you’d think I’d know better. Every time a Bindable object is modified Flex does a bunch of event dispatching and other plumbing. In this case the Label which is bound to the ffCount variable is also doing a bunch of work each time ffCount changes. As you can see, the results are not great. It takes almost a full second (on my machine) to do the filter on 20,000 items. Obviously this isn’t right.

Lesson learned: A Flex application should never, ever, ever, update Bindable objects in filter functions or other places where the user won’t ever be able to distinguish something changing that rapidly.

A better approach is to update a non-Bindable variable in the loop or filter function, then when the loop or filter is done, copy the non-Bindable variable to a Bindable one. You can see the updated demo using this approach here:

Demo 2
Source 2

This approach is about 10x faster! And only a little bit more work. In this case it’s very easy to be notified when the filter has completed and then update the Bindable variable:

if (event.kind == CollectionEventKind.REFRESH)
{
    ffCount = _ffCount;
}

In retrospect this seems like a silly mistake but I would not be surprised if this sort of thing is causing performance problems in many Flex applications. Data Binding is a very powerful part of Flex but it can also cause performance problems when used incorrectly. I hope this helps some of you to avoid this pitfall. Let me know what you think.

This entry was posted in Flex. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

9 Comments

  1. Posted August 27, 2008 at 11:52 pm | Permalink

    Bindings are great for automatic updates, but more than often they should be used in conjunction with commitProperties. That is, instead of binding directly to a property you can use BindingUtils.bindSetter and call invalidateProperties when the bound value changes. That way you will only update once every frame, regardless of how many times the bindable property changes.

  2. bgen
    Posted August 28, 2008 at 3:41 am | Permalink

    What about using the event specifier with Bindable, i.e. [Bindable(event="ffCountChangeEvent")], then dispatching that event whenever you want the binding to occur? That would prevent the unneccessary overhead from occuring every time the property changes. This is just my first thought on what you’ve said, so there might be other implications I’m not considering…

  3. Posted August 28, 2008 at 4:52 am | Permalink

    Michael Labriola did an awesome presentation at 360|Flex on the same subject : http://link.brightcove.com/services/link/bcpid1733261879/bclid1729365228/bctid1741212660?src=mrss There is quite a bit of code that goes into making binding work….

  4. Posted August 28, 2008 at 5:58 am | Permalink

    Thanks Theo and bgen. Both of those are also good suggestions for dealing with this.

    Thanks Nick. Mike really knows this stuff inside and out. So I’ll have to watch that talk.

    -James

  5. Posted September 9, 2008 at 10:32 am | Permalink

    Hi James, I’m preparing a presentation about performance optimization in Flex for an event in Madrid and was wondering if you’d mind if I use this example when talking ’bout bindings.

    Thanks in advanced!

    Regards

    Alberto

  6. Posted September 10, 2008 at 6:26 am | Permalink

    Hi Alberto,

    Feel free to use anything on my blog for your presentation.

    Let me know how it goes.

    -James

  7. Posted January 3, 2009 at 1:10 pm | Permalink

    I am having trouble binding with what I thought was a simple problem. To track time I have created a 3 table database. Projects, Personnel and Trackers. I would like to get data from the projects and Personnel tables in order to populate combo boxes and commit new data to the trackers table. How do I do this? I am a rank amature… this is my first project, but I think it is going to help my company a ton.
    Thanks in advance for any help you can provide.
    Krista

  8. Posted January 10, 2009 at 10:25 am | Permalink

    Hi Krista,

    There are lots of ways to do that. And it also depends on if you want to do it the right way or the easy way. The easy way:
    - One big MXML file
    - HTTPService requests that get the data and bind it to the combo boxes
    - HTTPService that can send an update to the server

    There are tutorials online that can help you. And there is always my book First Steps in Flex that will also help.

    Let me know how it goes.

    -James

  9. Roman
    Posted February 12, 2009 at 1:05 am | Permalink

    @Theo
    Can you give me link/article/bokk about using commitProperties with Binding and problems with it.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

Subscribe without commenting

  • About James Ward



    View James Ward's profile on LinkedIn

  • First Steps in Flex by James Ward and Bruce Eckel




  • Twitter Updates


  • Tour de Flex