A TableView performance test case. Can you help?

You must Login before you can answer or comment on any questions.

I was wondering if you all might be able to help me fine tune the performance of a TableView for a commercial grade iOS application I'm working on. Perhaps other future developers would also benefit from this test case.

Below is the app.js file for a simple test project that contains nothing but a single table with 35 rows. The rows are fairly complex, containing 8 labels arranged in a way that pretty closely resembles the actual app I'm working on. I'm getting pretty poor performance on the iPhone 4 from this configuration -- especially when first scrolling the table, bringing rows in to view. If you first start the application and attempt to scroll quickly to the bottom there is huge, huge lag. Once all the rows have come in to view the performance is a lot better, but it still doesn't feel as smooth as other native applications such as ebay, facebook or godaddy, which use table rows of similar complexity.

A few things of note:

  • All the TableViewRow objects share the exact same class name.
  • I'm avoiding auto width or height whenever possible (though it is needed occasionally).
  • I've tried to cut down the number of views I'm using, opting to absolutely position labels, rather than adding extra views with horizontal or vertical layouts.
  • I tried to use an imageView but it crashed my application every time, so I had no other choice but to use a view with backgroundImage.
  • I know that opaque labels perform better, but my final table will have even more graphic fidelity, such as images and a gradient, so all labels have to be transparent.

Anything else I should be doing? Any tips for perhaps pre-rendering the table and its rows so they are not cached and laggy? Thanks very much.

var win = Ti.UI.createWindow({  
    title:'Test',
});
 
var tableView = Ti.UI.createTableView({
    minRowHeight: 75
});
win.add(tableView);
 
var rows = [];
for (var i = 0; i < 35; i++) {
    rows.push(createRow());
}
 
function createRow() {
    var row = Ti.UI.createTableViewRow({
        left: 0,
        right: 0,
        top: 0,
        bottom: 0,
        className: 'className',
        layout: 'horizontal'
    });
 
    // Main left container.
    var leftView = Ti.UI.createView({
        left: 10,
        top: 10,
        bottom: 0,
        width: 220
    });
    row.add(leftView);
 
    leftView.add(Ti.UI.createView({
        top: 0,
        left: 0,
        height: 16,
        width: 16,
        backgroundImage: 'images/test.png'
    }));
 
    leftView.add(Ti.UI.createLabel({
        text: 'Big font, longer text',
        top: 0,
        height: 20,
        width: 'auto',
        left: 25,
        font: {fontSize: 16, fontWeight: 'bold'}
    }));
 
    leftView.add(Ti.UI.createLabel({
        text: 'Small 1',
        top: 25,
        left: 25,
        height: 15,
        font: {fontSize: 12, fontWeight: 'bold'}
    }));
 
    leftView.add(Ti.UI.createLabel({
        text: 'Small 2',
        top: 40,
        left: 25,
        height: 15,
        font: {fontSize: 12}
    }));
 
    leftView.add(Ti.UI.createLabel({
        text: 'Small 3',
        top: 25,
        right: 0,
        height: 15,
        font: {fontSize: 12, fontWeight: 'bold'},
        width: 'auto'
    }));
 
    leftView.add(Ti.UI.createLabel({
        text: 'Small 4',
        top: 40,
        right: 0,
        height: 15,
        font: {fontSize: 12},
        width: 'auto'
    }));
 
    var rightView = Ti.UI.createView({
        left: 20,
        top: 10,
        bottom: 0,
        width: 'auto'
    });
    row.add(rightView);
 
    rightView.add(Ti.UI.createLabel({
        text: 'Small 4',
        top: 0,
        height: 20,
        width: 'auto',
        font: {fontSize: 13, fontWeight: 'bold'},
        textAlign: 'right'
    }));
 
    rightView.add(Ti.UI.createLabel({
        text: 'BIG',
        top: 20,
        height: 30,
        width: 'auto',
        font: {fontSize: 30, fontWeight: 'bold'}
    }));
 
    return row;
}
 
tableView.setData(rows);
 
win.open();

— asked 2 years ago by Jude Osborn
3 Comments
  • Also wanted to point out that I noticed the application, GetGlue, which was made with Titanium, has similar performance issues. If you open up a larger table of data and start scrolling you'll notice pretty major lag. The performance is a bit better than my table above, but not much. Hopefully this isn't an inherent Titanium problem. Again, all other non-Titanium applications I've tested feel much, much smoother.

    — commented 2 years ago by Jude Osborn

  • Interestingly enough, after I updated today to 1.7.3 final table scrolling is noticeably smoother. It's still nowhere near where it should be, but there is definitely a difference. It's comforting as a developer to see such performance gains.

    — commented 2 years ago by Jude Osborn

  • I have the exact same problem. When drawing around 25 rows it can take up to 6 seconds on the iPhone 3G and around 2 on the iPhone 4. This isn't acceptable.

    — commented 1 year ago by John Johnson

3 Answers

Yeah, this is super sad. I am experiencing the exact same problems as you. Got about 4 labels and an image view in each row and using class names. Same lagging behavior. It is very sad because every other part of Titanium works very well. It is a Titanium issue and not an issue with your code I´m afraid. I tried many combinations of row content and all lags, especially when using image views. Let´s hope that Appcelerator fixes these performance problems with tables before adding more features because they are such common content items in an app.

So should I mark the above gloomy answer as "best answer"? I'm really starting to wonder if Titanium is the tool for the job. At this point I'm pretty sure the average user is going to assume my app is NOT native, due to the extremely laggy scroll behavior. This is a pretty serious issue.

— answered 2 years ago by Jude Osborn
answer permalink
1 Comment
  • Since this is a reproducable problem (both in my code above and in the GetGlue app) I created a Jira ticket. However, if anyone else has suggestions I'm still listening.

    — commented 2 years ago by Jude Osborn

Any progress on this matter? I have the exact same performance problems with tableviews

— answered 2 years ago by Mads Møller
answer permalink
3 Comments
  • As I mentioned above, an SDK update (I think it was 1.7.3 final) made a big difference. I also found that there were just a lot of memory leaks in my app that were affecting performance. My app is now acceptable, but I think there could be improvements.

    — commented 2 years ago by Jude Osborn

  • im using 1.7.5 and the tableview listing is running slow. I have an imageview, 5 labels where two of these uses a custom font. Thats not a great cocktail for Appcelerator...

    Anyone know if 1.8 will address this?

    — commented 2 years ago by Mads Møller

  • In my experience, newer versions of Titanium did improve the speed somewhat, but the biggest problem was simply the way I was programming my app in general. Once I took the time to fine tune it and ensure I wasn't opening the same screen multiple times, destroying objects as necessary, etc., etc., the scrolling of tables in my app went from practically unusable to just fine. The difference was huge.

    It's a bit hard to give you specific suggestions without going through all your source code, but I think fine tuning is the key here. My app tables were absolutely HORRIBLE at first and it was a huge worry for me, but they naturally gained in speed slowly as I fine tuned the applications until I suddenly realized they were pretty smooth. The following video was tremendously helpful:

    http://vimeo.com/29804284

    — commented 2 years ago by Jude Osborn

Your Answer

Think you can help? Login to answer this question!