Project: titanium
Issue TIMOB-23625: Windows: Progressive loading for ListView/TableView
Currently {{TableView}} and {{ListView}} has performance issue where it can not load chunk of data at once because it requires a lot of CPU/memory resource. We might want to introduce UI virtualization or progressive data loading or something like that so that we can load data as many as possible. Per comments in TIMOB-23411 {quote} I'm guessing we need to do some deep looks into trying to optimize our usage of the ListView implementation under the hood to avoid these issues. I'm guessing perhaps the way the controls are nested, we're hitting a use case where the phone's UI virtualization for the ListView is defeated. See https://msdn.microsoft.com/windows/uwp/debug-test-perf/optimize-gridview-and-listview The critical portion being: bq. The concept of a viewport is critical to UI virtualization because the framework must create the elements that are likely to be shown. In general, the viewport of an ItemsControl is the extent of the logical control. For example, the viewport of a ListView is the width and height of the ListView element. Some panels allow child elements unlimited space, examples being ScrollViewer and a Grid, with auto-sized rows or columns. When a virtualized ItemsControl is placed in a panel like that, it takes enough room to display all of its items, which defeats virtualization. Restore virtualization by setting a width and height on the ItemsControl. Lots more links out there on GridView/ListView performance problems: - https://blogs.msdn.microsoft.com/alainza/2014/09/03/listview-basics-and-virtualization-concepts/ - https://www.interact-sw.co.uk/iangblog/2014/07/15/phone-listview-grouping - http://nanovazquez.com/2013/11/28/windows-8.1-gridview-and-listview-performance-improvements/ - http://stackoverflow.com/questions/28944705/multiple-listview-ui-virtualization - http://mikaelkoskinen.net/post/winrt-xaml-gridview-performance-problems-on-windows-rt-tablets Long story short? First make sure you explicitly set a size on the ListView impl and not let it FILL, or it'll never virtualize. Second, it looks like sometimes grouping can basically kill UI virtualization as well, as each group effectively becomes auto-scaled in size to contain it's items. {quote} We also want to tackle with performance difference between {{TableView}} and {{ListView}}, currently creating ListView data is 5x times slower than TableView. It is likely because ListView is relatively complex component with custom template support, but we'd like to close the gap as much as we can. *TableView* {code} var win = Ti.UI.createWindow(); var data = []; var start = +new Date(); for (var i = 0; i < 20; i++) { var sectionFruit = Ti.UI.createTableViewSection({ headerTitle: 'Fruit' }); sectionFruit.add(Ti.UI.createTableViewRow({ title: 'Apples' })); sectionFruit.add(Ti.UI.createTableViewRow({ title: 'Bananas' })); data.push(sectionFruit); var sectionVeg = Ti.UI.createTableViewSection({ headerTitle: 'Vegetables' }); sectionVeg.add(Ti.UI.createTableViewRow({ title: 'Carrots' })); sectionVeg.add(Ti.UI.createTableViewRow({ title: 'Potatoes' })); data.push(sectionVeg); var sectionFish = Ti.UI.createTableViewSection({ headerTitle: 'Fish' }); sectionFish.add(Ti.UI.createTableViewRow({ title: 'Cod' })); sectionFish.add(Ti.UI.createTableViewRow({ title: 'Haddock' })); data.push(sectionFish); } var table = Ti.UI.createTableView({ data: data }); Ti.API.info('Elapsed: ' + (+new Date() - start)); win.add(table); win.open(); {code} *ListView* {code} var win = Ti.UI.createWindow({ backgroundColor: 'green' }); var listView = Ti.UI.createListView(); var sections = []; var start = +new Date(); for (var i = 0; i < 20; i++) { var fruitSection = Ti.UI.createListSection({ headerTitle: 'Fruits' }); var fruitDataSet = [ { properties: { title: 'Apple' } }, { properties: { title: 'Banana' } }, ]; fruitSection.setItems(fruitDataSet); sections.push(fruitSection); var vegSection = Ti.UI.createListSection({ headerTitle: 'Vegetables' }); var vegDataSet = [ { properties: { title: 'Carrots' } }, { properties: { title: 'Potatoes' } }, ]; vegSection.setItems(vegDataSet); sections.push(vegSection); var fishSection = Ti.UI.createListSection({ headerTitle: 'Fish' }); var fishDataSet = [ { properties: { title: 'Cod' } }, { properties: { title: 'Haddock' } }, ]; fishSection.setItems(fishDataSet); sections.push(fishSection); } listView.sections = sections; Ti.API.info('Elapsed: ' + (+new Date() - start)); win.add(listView); win.open(); {code}
Story points: 13