Widget 2.0 Tableview Performance

I have a BIG issue with the new Widget 2.0 tableviews. First of all I appreciate all the hard work that went into the new Widgets, great job guys!!! But the new tableview from a performance stand point is horrible. The simple example running on the simulator works fine but once things get a little more complicated things go bad. If I take the example and add a sub text and instead of 100 rows I render 2000 things look ok in the simulator but on a device(retina iPad) the performance is horrible and slows down the whole UI as well as very bad scrolling.  I understand that in a game 2000 rows might seem excessive but I’m using Corona for an EHR mobile app and having 2000 patients isn’t far fetched at all(we have a couple providers with a couple thousand) and this performance hurts. This wasn’t the case with the old widgets so this happening right near the end of development really throws a wrench in things. I’m sure the old widgets removed the row from memory when it was off screen and had better memory management. Is there something I can do to get better performance?

Here is a simple test case to see how performance struggles on a device. Note you have to install it on a device to see the poor performance.

local group = display.newGroup() local widget = require( "widget" ) screen = { left = display.screenOriginX, top = display.screenOriginY, right = display.contentWidth - display.screenOriginX, bottom = display.contentHeight - display.screenOriginY }; -- Handle row rendering local function onRowRender( event ) local phase = event.phase local row = event.row local rowTitle = display.newText( row, "This is displaying Row " .. row.index, 0, 0, nil, 14 ) rowTitle.x = row.x - ( row.contentWidth \* 0.5 ) + ( rowTitle.contentWidth \* 0.5 ) rowTitle.y = (row.contentHeight \* 0.5)-10 rowTitle:setTextColor( 0, 0, 0 ) local rowSubTitle = display.newText( row, "This is displaying Sub Row " .. row.index, 0, 0, nil, 12 ) rowSubTitle.x = row.x - ( row.contentWidth \* 0.5 ) + ( rowSubTitle.contentWidth \* 0.5 ) rowSubTitle.y = (row.contentHeight \* 0.5)+10 rowSubTitle:setTextColor( 93, 93, 93 ) end -- Handle touches on the row local function onRowTouch( event ) local phase = event.phase if "press" == phase then print( "Touched row:", event.target.index ) end end -- Create a tableView local tableView = widget.newTableView { top = screen.top, left = screen.left, width = (screen.right-screen.left), height = (screen.bottom-screen.top), onRowRender = onRowRender, onRowTouch = onRowTouch, } group:insert( tableView ) -- Create 2000 rows for i = 1, 2000 do local isCategory = false local rowHeight = 40 local rowColor = { 255, 255, 255 } local lineColor = { 220, 220, 220 } -- Insert the row into the tableView tableView:insertRow { isCategory = isCategory, rowHeight = rowHeight, rowColor = rowColor, lineColor = lineColor, } end

Hi @chevol,

You make a valid point here, and we’ll look into this post-next-public-release (it won’t make it in before that, regrettably).

On that note, I’m just curious, from a design standpoint would it be better to somehow sort/divide your “data” into a more manageable series of tableviews? I don’t presume to understand exactly how your app works or the data involved in the view, but considering this from a simple “user standpoint”, I would never want to sort through 2000+ rows in a table view. Even 1000 would be overwhelming to me, as an end user.

Could the data be sorted alphabetically, as in, 26 buttons or rows (letters of the alphabet) that bring up a new tableview with those records? Or maybe some other method of sorting?

Again, I’m not suggesting that you re-tool your entire app just because of the new tableview behavior, I’m only suggesting that from a useability standpoint, maybe there’s a better method. You might also consider something like a tableview of 200 items, then the last item in the series is “See 200 more…” and that loads a new set of 200, etc.

Anyway, thanks for the comment, we’re taking all of this into consideration. :slight_smile:

Brent

Hey Brent,

    You are correct about sorting/dividing the data and we aren’t showing the user all 2000 rows, we do sort and divide the best we can. The 2000 rows was just as an example and so the test code I sent works and is as simple as possible. In our case we have lots of data because our clients can have multiple locations and each location can have lots of patients, we use multiple tableviews on a screen to accomplish the sorting and dividing. Without giving you code to replicate the issue with like 4 tableviews I decided to consolidate it into a single really large tableview. But if you put a couple (3-4) tableviews on screen with many rows you get the same performance issues. On a tablet I can think of many reasons as to why you’d use multiple tableviews.

Funny, I am just about to rewrite for the new widgets. Is it possible to keep using the old widget tableview as opposed to going with 2.0 in light of the performance decreases? Or is the new tableview widget faster than the old one anyhow? (I only have 40 or so rows.)

Hive,

  Corona open-sourced the old widget library - 

https://github.com/coronalabs/widget-v1

Hi @Hive,

40 rows in the new table view will be fine. I’d go ahead and start tinkering with it. Also, we’re looking into how we might improve this in a future daily build, for table views that use an immense amount of rows.

Brent

I think that the performance even on smaller lists of data say 100 or so is still quite slow compared to the old 1.0 Widgets.  Using corona for things other than games is difficult if performance on larger data sets is not considered in the design of these widgets.  I would really like to see performance on this.  My testing shows that you seem to be rendering ALL rows upon insertion rather than on demand as they enter the screen.  I think that the original post from cheval says it all.  Just want to make sure you know that there are others out here trying to build utilities and other non-game based solutions with Corona and need larger data sets to be considered in the design.

In my case due to the DB queries associated with rendering each row the current solution breaks down even with 50 rows due to the fact that while only 5 rows are on screen, all 50 are being rendered even when off screen.

@mslack one thought, If you’re in a jam and don’t want to deal w/ widget 1 but can’t use widget 2 yet due to performance you could also try widget candy.  I haven’t tested the performance of their scrolling list with a huge dataset but in general their products have been great.

http://www.x-pressive.com/WidgetCandy_Corona/media.html

Just to let you guys know, I am working on this and am close to a resolution.

I will keep you posted.

Thanks for the update Danny!

Thanks Danny.  congrats on the release yesterday - big step forward.  

Hi @chevol,

You make a valid point here, and we’ll look into this post-next-public-release (it won’t make it in before that, regrettably).

On that note, I’m just curious, from a design standpoint would it be better to somehow sort/divide your “data” into a more manageable series of tableviews? I don’t presume to understand exactly how your app works or the data involved in the view, but considering this from a simple “user standpoint”, I would never want to sort through 2000+ rows in a table view. Even 1000 would be overwhelming to me, as an end user.

Could the data be sorted alphabetically, as in, 26 buttons or rows (letters of the alphabet) that bring up a new tableview with those records? Or maybe some other method of sorting?

Again, I’m not suggesting that you re-tool your entire app just because of the new tableview behavior, I’m only suggesting that from a useability standpoint, maybe there’s a better method. You might also consider something like a tableview of 200 items, then the last item in the series is “See 200 more…” and that loads a new set of 200, etc.

Anyway, thanks for the comment, we’re taking all of this into consideration. :slight_smile:

Brent

Hey Brent,

    You are correct about sorting/dividing the data and we aren’t showing the user all 2000 rows, we do sort and divide the best we can. The 2000 rows was just as an example and so the test code I sent works and is as simple as possible. In our case we have lots of data because our clients can have multiple locations and each location can have lots of patients, we use multiple tableviews on a screen to accomplish the sorting and dividing. Without giving you code to replicate the issue with like 4 tableviews I decided to consolidate it into a single really large tableview. But if you put a couple (3-4) tableviews on screen with many rows you get the same performance issues. On a tablet I can think of many reasons as to why you’d use multiple tableviews.

Funny, I am just about to rewrite for the new widgets. Is it possible to keep using the old widget tableview as opposed to going with 2.0 in light of the performance decreases? Or is the new tableview widget faster than the old one anyhow? (I only have 40 or so rows.)

Hive,

  Corona open-sourced the old widget library - 

https://github.com/coronalabs/widget-v1

Hi @Hive,

40 rows in the new table view will be fine. I’d go ahead and start tinkering with it. Also, we’re looking into how we might improve this in a future daily build, for table views that use an immense amount of rows.

Brent

I think that the performance even on smaller lists of data say 100 or so is still quite slow compared to the old 1.0 Widgets.  Using corona for things other than games is difficult if performance on larger data sets is not considered in the design of these widgets.  I would really like to see performance on this.  My testing shows that you seem to be rendering ALL rows upon insertion rather than on demand as they enter the screen.  I think that the original post from cheval says it all.  Just want to make sure you know that there are others out here trying to build utilities and other non-game based solutions with Corona and need larger data sets to be considered in the design.

In my case due to the DB queries associated with rendering each row the current solution breaks down even with 50 rows due to the fact that while only 5 rows are on screen, all 50 are being rendered even when off screen.

@mslack one thought, If you’re in a jam and don’t want to deal w/ widget 1 but can’t use widget 2 yet due to performance you could also try widget candy.  I haven’t tested the performance of their scrolling list with a huge dataset but in general their products have been great.

http://www.x-pressive.com/WidgetCandy_Corona/media.html

Danny,

Just noting that i do not see this solved in 1080.  Don’t know if you have had time to complete the work you mentioned or not.  Updating the observed status of this issue.

Cheers,

m

Just to let you guys know, I am working on this and am close to a resolution.

I will keep you posted.