Bug 56896 - ListViews for lists with many elements regressed in performance on iOS
Summary: ListViews for lists with many elements regressed in performance on iOS
Alias: None
Product: Forms
Classification: Xamarin
Component: iOS (show other bugs)
Version: 2.3.5
Hardware: Macintosh Mac OS
: Highest critical
Target Milestone: ---
Assignee: Samantha Houts [MSFT]
Depends on:
Reported: 2017-05-26 22:14 UTC by Frank Schwieterman
Modified: 2017-07-20 20:43 UTC (History)
12 users (show)

See Also:
Tags: ac, ios, listview, performance, xamexttriage, fr, xamextfollowed
Is this bug a regression?: Yes
Last known good build:

Attached are the logs generated during defect verification (4.14 KB, application/x-zip-compressed)
2017-06-28 12:41 UTC, Saurabh Paunikar

Description Frank Schwieterman 2017-05-26 22:14:01 UTC
# Steps to reproduce

Pull the project: https://github.com/trainerroad/ListviewBugRepro
Run it on iOS

# Expected behavior

The listview should load quickly.  The debug output should show a small number of calls to the InstrumentedViewCell and InstrumentedGrid.

# Actual behavior

The listview loads slowly.  Rather than constructor <100 InstrumentedViewCells, it creates over 25000.

# Supplemental info (logs, images, videos)

Watching the debug output, running Xamarin Forms with Mono Runtime on iOS I see:

InstrumentedViewCell counts: constructor: 25029, OnPropertyChanged NameScope: 25029, OnPropertyChanged Height: 25027, OnPropertyChanged RenderHeight: 25027, OnPropertyChanged View: 25027, OnPropertyChanged BindingContext: 25027, OnBindingContextChanged: 25027, OnPropertyChanged Index: 25027, OnParentSet: 25027, OnPropertyChanged Parent: 25027, OnPropertyChanged RealCell: 13, OnAppearing: 13
InstrumentedGrid counts: constructor: 25027, InvalidateLayout: 25027, OnSizeAllocated: 25053, OnParentSet: 25027, OnBindingContextChanged: 25027, LayoutChildren: 26

This is the InstrumentedViewCell and InstrumentedGrid counting the number of times a method was called (for all instances in the process).  This is way too hay.

If I run on Android, its much better (still Xamarin Forms, Mono Runtime

InstrumentedGrid counts: constructor: 20, InvalidateLayout: 20, OnSizeAllocated: 39, OnParentSet: 20, OnBindingContextChanged: 38, OnMeasure: 19, OnSizeRequest: 19, LayoutChildren: 19
InstrumentedViewCell counts: constructor: 22, OnPropertyChanged NameScope: 22, OnPropertyChanged Height: 20, OnPropertyChanged RenderHeight: 20, OnPropertyChanged View: 20, OnPropertyChanged BindingContext: 38, OnBindingContextChanged: 38, OnPropertyChanged Index: 38, OnParentSet: 20, OnPropertyChanged Parent: 20, OnPropertyChanged Renderer: 19, OnAppearing: 19

If I run iOS on a previous version of Xamarin Forms, its better (Xamarin, Mono Runtime 4.8.1):

InstrumentedViewCell counts: constructor: 69, OnPropertyChanged NameScope: 69, OnPropertyChanged Height: 67, OnPropertyChanged RenderHeight: 67, OnPropertyChanged View: 67, OnPropertyChanged BindingContext: 67, OnBindingContextChanged: 67, OnPropertyChanged Index: 67, OnParentSet: 67, OnPropertyChanged Parent: 67, OnPropertyChanged RealCell: 33, OnAppearing: 33
InstrumentedGrid counts: constructor: 67, InvalidateLayout: 67, OnSizeAllocated: 133, OnParentSet: 67, OnBindingContextChanged: 67, OnMeasure: 1, OnSizeRequest: 1, LayoutChildren: 66

The differences between iOS and Android (all are <100) are likely due to the display size of the different devices, and not a problem.  When it has to create 25000 instances to render a <20 rows, thats a problem.

# Test environment (full version information)

I hit this issue on our original application running Visual Studio 2015.  The isolated repro in the github issue was put together on Visual Studio for Mac.
Comment 1 Frank Schwieterman 2017-05-26 22:21:50 UTC
The problematic list looks like:

	<ListView HasUnevenRows="true" CachingStrategy="RecycleElement" x:Name="TheListView">
						<local:InstrumentedViewCell Height="50">
								<Label Text="{Binding .}" BackgroundColor="Green" />
                        <local:InstrumentedViewCell Height="60">
                                <Label Text="{Binding .}" />

The issue still repros without the DataTemplateSelector (replaced with just the InstrumentedViewCell/InstrumentedGrid/Label).  I included the DataTemplateSelector so the repro is closer to our original application.

  The InstrumentedViewCell.Height is included to make it easier for the ListView to determine the row heights (this was needed on the earlier version of Xamarin Forms to get good performance on iOS).  For this repro removing the Height attribute causes the problem to go away, but that doesn't work for our original application.  So removing the Height property is not a work-around that works for us.
Comment 2 Frank Schwieterman 2017-05-26 22:27:34 UTC
Oh yeah, the master branch has the repro.  Branch 'earlier-xamarin-forms' has an earlier version of Xamarin that doesn't repro the problem, demonstrating this is a regression.

Frank Schwieterman
Trainer Road LLC
Comment 3 Jimmy [MSFT] 2017-06-02 00:03:03 UTC
I ran the repro project on an iPhone device and I can confirm this issue. This seems to only be occurring on iOS.

When I launched the app, there was a significant loading time for the ListView to display. The project uses an ItemSource with 5000 items and it took about four and half minutes for the ListView to load.

As mentioned in comment 1, minimizing the ListView to use a single ItemTemplate instead of a DataTemplateSelector does not make a difference.

Downgrading the project back to Forms showed a significant difference in loading time. Now the list loaded in a couple of seconds with the original 5000 item list so this does appear to be a regression in Forms and not Xamarin.iOS itself.

### Regression Status   BAD
2.3.5-pre3  BAD   BAD   GOOD
Comment 4 Samantha Houts [MSFT] 2017-06-15 17:26:30 UTC
Comment 5 Rui Marinho 2017-06-23 10:53:32 UTC
Should be fixed on 2.3.5-pre5
Comment 9 Frank Schwieterman 2017-07-20 20:43:17 UTC
In case anyone wants to look at the original repro, it is in branch bugzilla-56896 at https://github.com/trainerroad/ListviewBugRepro

Notice (2018-05-21): bugzilla.xamarin.com will be switching to read-only mode on Thursday, 2018-05-25 22:00 UTC.

Please join us on Visual Studio Developer Community and GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs and copy them to the new locations as needed for follow-up. The See Also field on each Bugzilla bug will be updated with a link to its new location when applicable.

After Bugzilla is read-only, if you have new information to add for a bug that does not yet have a matching issue on Developer Community or GitHub, you can create a follow-up issue in the new location. Copy and paste the title and description from this bug, and then add your new details. You can get a pre-formatted version of the title and description here:

In special cases you might also want the comments:

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Note You need to log in before you can comment on or make changes to this bug.