Enhancing Titanium: Speeding up data binding

Rene Pot
All Titanium

--

So you’ve set up data binding in Alloy, you do an API call (or execute an SQL query) to fetch your data, and you manually add them to collections. This is the right way to do it right? Well… yes it is, but it can get very slow once you’ve got quite a lot of results, even though it is a listview.

There is a very simple workaround, or fix actually, to solve this problem. But first, let me explain what actually is happening that makes it so slow:

  • you fetch 50 results from an API endpoint
  • you loop through the results
  • first loop: you create a model, and add it to collection
  • UI re-renders because of it
  • second loop: you create a model, and add it to collection
  • UI re-renders
  • etc…

See the problem? Every time you add a model to the collection, the UI re-renders. Now… when adding 10 items, you probably won’t even notice this. With 50, you will notice this for sure, but not a lot. Just think about it when you add 500, or 1000 items. It will be slow as hell!

The Solution is simple

Simple example, here is a ListSection that has data-binding set up.

<ListSection
dataCollection=”myCollection”
dataTransform=”parseData”>

So when you add 1 item to your collection, it will be rendered, and will even walk through your parseData function so you can manipulate some data. But, you need to prevent this, by adding a silent parameter

myCollection.add(model, {silent: true});

Now, when you add a model to your collection, it won’t re-render, so it can add all 500 models in no-time, but it still won’t show up on your screen. To do this, you need to add the dataFunction property to your XML, like this:

<ListSection
dataCollection=”myCollection”
dataTransform=”parseData”
dataFunction=”refreshListView”>

Then, you don’t have to define this function in your controller! You shouldn’t! You should just call this function, as soon as you’ve added all your models to your collection, so you basically end up with code similar to this:

_.each(items, function(item){
myCollection.add(Alloy.createModel(‘item’, item), {silent: true});
});
refreshListView();

And now, you’ve got a much better performing ListView, with the same data, and without UI lock. Congratulations!

--

--