Xamarin.forms: [iOS] CollectionView scrolling is jittery

Created on 14 Aug 2019  路  25Comments  路  Source: xamarin/Xamarin.Forms

Description

I was hoping to see silky smooth scrolling with CollectionView since a lot of layouting and virtualization are native. A simple item template containing an image and two labels creates scroll performance issues, especially when the scroll slows down to come to an end.

Steps to Reproduce

  1. Run the repro on a physical device (tested on XS)
  2. Scroll down
  3. Observe that scrolling gets jumpy especially when it decelerates
  4. If unable to reproduce, you should scroll up and down several times

Expected Behavior

Scrolling should be perfect to meet production standards. Also, compare this to the Android project. You'll notice that Android scrolls better.

Actual Behavior

Scrolling is not perfect.

I have also observed that removing both labels and using FFImageLoading for images makes scrolling better, so at minimum we need to understand why labels create stutter.

Basic Information

  • Version with issue: 4.3.0.1032-nightly
  • IDE: VS2019
  • Affected Devices: XS and possibly other iPhone devices

Reproduction Link

App1TT.zip

collectionview performance high high impact bug

Most helpful comment

@nor0x This is on the high priority list of things to resolve. We're working on it!

All 25 comments

I've used CollectionView for a complicated view template and got even much more jittery scrolling.
After investigation I found the reason. Method from the ItemsViewController
ItemsViewController.cs#L209
creates content for template on every cell reuse. I think we should avoid this
and make something like this (IT works much better, but looks like a crazy stuff :) and would not work with templateSelector )

      ` var template = ItemsView.ItemTemplate;
        var item = ItemsView.ItemsSource.GetItem(indexPath.Row);
        template = template.SelectDataTemplate(item, ItemsView);
        if (cell.VisualElementRenderer == null)
        {
            var view = template.CreateContent() as View;
            var renderer = createRenderer(view);
            cell.SetRenderer(renderer);
            ItemsView.AddLogicalChild(view);
        }

        cell.SetRenderer(cell.VisualElementRenderer);
        cell.VisualElementRenderer.Element.BindingContext = item;`

I'm guessing this is related to
https://github.com/xamarin/Xamarin.Forms/issues/7128

When testing this on an iPad (6th Generation) with 12.4 the CollectionView was crashing even if I didn't have labels present

You could also see this issue if you go to CollectionView Gallery -> Observable Collection Galleries -> Multi-item add/remove, no index.

I set up a StopWatch to monitor method invocations in ApplyTemplateAndDataContext. The most expensive calls seem to be the following three lines:

var renderer = CreateRenderer(view);
cell.SetRenderer(renderer);
view.BindingContext = ItemsSource[indexPath];

As Artemio mentioned, creating a renderer and setting its binding context for a complex cell will be quite slow. If we account for a multi-column grid layout, then it can get even worse. Hmm.

Also, I wonder if we need to register / dequeue multiple cells here based on data template. Right now, everything seems to point to generic horizontal / vertical reuse ids based on scroll direction.

Also, I wonder if we need to register / dequeue multiple cells here based on data template. Right now, everything seems to point to generic horizontal / vertical reuse ids based on scroll direction.

I think you're on the right track - this is the next step for optimization. I want to see how things look with #7285 in place, but if we're looking to eke out some more performance then pooling the cells by template makes a lot of sense.

Especially if someone is using DataTemplateSelector for effects like alternating background colors - with the wrong number of items on screen, we could end up _never_ reusing a renderer. Pooling would address that.

I can confirm that even with simple cells (grid with 3 labels) and a DataTemplateSelector, the scroll performance is bad: jittering even with a couple of row. Had to go back to listview.....

I though that collectionview aims to have much better performance than listview but for my usecase is not true.
Sad to see this issue in the Backlog, only to me this seems a HUGE problem? I mean, the whole point to collectionview is to replace, for the better, the listview.

I tried to do a fix but myself but... i just cant :)

EDIT:
Just to clarify: this happens only using DataTemplateSelector

Any updates on this? I'm having the same issues when using a DataTemplateSelector with cells that contain images. In my case it crashes on fast scrolling gestures - this is a pretty critical bug and complete blocker for us @samhouts

@nor0x This is on the high priority list of things to resolve. We're working on it!

Will this be fixed in the next release?

It is really a bad experience for the users. We fear to get bad ratings for our App, because of this...

Any ETA on when we can expect this fix? It's currently blocking releasing my app due to the behavior

Same issue here and still awaiting for a fix.

For those still experiencing this issue - have you tried a more recent version? The original report was for 4.3, and we've made several changes to the CollectionView's iOS implementation since then.

I'd be interested to hear whether you are still experiencing issues with 4.6 (the latest stable version) and/or the 4.7 pre-release.

For those still experiencing this issue - have you tried a more recent version? The original report was for 4.3, and we've made several changes to the CollectionView's iOS implementation since then.

I'd be interested to hear whether you are still experiencing issues with 4.6 (the latest stable version) and/or the 4.7 pre-release.

I'm on xamarin 4.6, testing a collection view with template selector(data templates can present images, labels, audio controler, buttons) and my conclusion is that's clear that had improvements in performance but if I say it's performing ideal, I would be lying. Although, yes, I'm seeing improvements comparing to xamarin 4.3/4.4, mainly when scrolling slow(seems almost perfect), but when scrolling fast it freezes a little bit and also, I can see clearly the cells being altered, it's weird but is faster than was.

Since this issue has [iOS] in title, I think it's important inform that this issue occurs in android also.

@ederjbezerra That's good information, thanks! You mentioned problems with a template selector - are you seeing the same issues with a single template? It sounds like you have a selector with 4 templates - is that accurate?

@ederjbezerra That's good information, thanks! You mentioned problems with a template selector - are you seeing the same issues with a single template? It sounds like you have a selector with 4 templates - is that accurate?

Actually, I have 15 possible templates. With a single template the jitter is smaller but I can't have only one and build others by changing elements visibility, would be a lot of work, maybe I would have a worse performance. I also tried to move from collection view to list view with cache strategy. Having only Labels it was amazingly faster, I was happy and started to move all the code to list view but when others elements entered in scene, the things got worse than with collection view and using RecycleElementAndDataTemplate caused app crashing.

For those still experiencing this issue - have you tried a more recent version? The original report was for 4.3, and we've made several changes to the CollectionView's iOS implementation since then.

I'd be interested to hear whether you are still experiencing issues with 4.6 (the latest stable version) and/or the 4.7 pre-release.

I'm using 4.7.0.968. The issue for me only shows up when I'm displaying images in the collection view.

@banjahman Are you using any other image loading libraries (e.g., FFImageLoading)? Are you loading local (file system or embedded) images, or images from the web?

I've been experimenting with as many different things that I can find to make the problem go away. I find it more prominent when using FFImageLoading. When I disabled that and use the built in Xamarin Image loading, the problem is somewhat bearable.

All of the images are coming from the web.

Still occurs on 4.7

@libin85 my investigations are on the Android platform not iOS.

@banjahman @hartez if you have issues with smooth scrolling and using FFImageLoading, I would humbly recommend you to use https://github.com/roubachof/Xamarin.Forms.Nuke instead.

Happens even on 4.8.
I am using multiple DataTemplates.
Its much worse on Android than on iOS.
Border line unusable when I have around 20 items due to the Jankyness.

I have found an additional "Bug" while creating an own DataGrid-Control.
Using CollectionView is needed ofc because I need multi-selection

So the issue appears after selecting an Item, then ordering the ItemsSource and replace current ItemsSource by the ordered one.
This causes massive lagging for me.
The only way I can prevent the lag is clearing the SelectedItem and SelectedItems-Property and this isn't a great choice.
Also I have found out, that if the selection still stays on the screen after replacing the ItemsSource it doesn't lag anymore, aswell as it doesn't lag anymore after selecting an other item.

Greetings
Primo :)

Was this page helpful?
0 / 5 - 0 ratings