listview slow building if listview.itemSource grow too large

It will take 20 seconds to build when ListView.itemSource has 20000+ items.
My ListView Item was very simple, just one button and one label.
I know the slow building will happen if I create so many items with ScrollView directly, because it has to build/render everything even some items din’t show on the Rect.
but this shouldn’t happen with ListView in my understanding: ListView only build/render items on the screen(or another screen plus for cache reason).
if the working of ListView is not like my understanding, what’s the point that it need we pass [makeItem / bindItem / height] to it?

Can you share your list view initialization code / list view attribute settings? It should not take that long, like you said, we only fill the viewport with as many elements as we need. Did you use the UI Debugger to see how many elements are created?
Is it possible that your item height is set to 0 or that your ListView is set to grow? It looks like it is creating all the items for some reason.

Thanks for reply.

Here is initialization of ListView:

            Action<VisualElement, int> bindItem = (item, i) =>
            {
                (item as ObjectFieldListDefaultUIItem).ShowAsset((string)(m_assetSource[i]), m_fastMode);
            };
            Func<VisualElement> makeItem = () =>
            {
                var newItem = new ObjectFieldListDefaultUIItem();
                newItem.onValueChanged += OnItemChanged;
                return newItem;
            };

            m_listView = new ListView(assetList, ObjectFieldListDefaultUIItem.HEIGHT, makeItem, bindItem);
            m_listView.style.flexGrow = 1f;
            m_listView.style.flexShrink = 0f;
            m_listView.style.flexBasis = 0f;
            m_listView.selectionType = SelectionType.Single;
            this.Add(m_listView);

Here is initialization of Item:

    public class ObjectFieldListDefaultUIItem : VisualElement
    {
        public const int HEIGHT = 28;
        public ObjectFieldListDefaultUIItem()
        {
            m_topArea = new Box();
            m_topArea.style.flexGrow = 1f;
            m_topArea.style.flexDirection = FlexDirection.Row;
            this.Add(m_topArea);

            m_detailButton = new Button();
            m_detailButton.text = "▶";
            m_detailButton.clicked += ShowDetail;
            m_topArea.Add(m_detailButton);

            m_pathField = new TextField();
            m_topArea.Add(m_pathField);
            m_pathField.style.flexGrow = 1f;
            m_pathField.multiline = true;
            m_pathField.RegisterCallback<MouseUpEvent>(OnPathFieldClick);
        }

        public void ShowAsset(string assetPath, bool fastMode = false)
        {
            //remove anyting
        }
    }

Here is the update function:

        public void Refresh(IEnumerable<string> assetList)
        {
            m_assetSource = assetList.ToList();

#if UNITY_2021_1_OR_NEWER
            m_listView.itemsSource = m_assetSource.Select(x=>x).ToList();
#else
            m_listView.itemsSource = m_assetSource.Select(x=>x).ToList(); //copy it for dynamic change item view
#endif

            m_listView.itemHeight = ObjectFieldListDefaultUIItem.HEIGHT;
            m_listView.bindItem = (item, i) =>
            {
                (item as ObjectFieldListDefaultUIItem).ShowAsset((string)(m_assetSource[i]), m_fastMode);
            };

#if UNITY_2021_1_OR_NEWER
            m_listView.Rebuild();
#else
            m_listView.Refresh();
#endif
        }

I have removed some logic code(the case still happen without these logic code).
My unity version is 2019.4.f1.

            m_listView.style.flexShrink = 0f;
            m_listView.style.flexBasis = 0f;

If I don’t add the code above, nothing can be render on the screen.The listview will not create any item, or the height of item will be 0 sometimes.I have to set the parent of listview also in many case.It seem that flexShrink and flexBasis cause it to calc/iter all items.
or

m_listView.Refresh();

could be problem?

I review my code when you confirm that things should not be happened like that with listview. And I found that for a 20000+ sorted string list, it will fallback to worst case(O(n^2)) if you sort it again without optimization.
I wrote the editor things so fast and It’s shame that I don’t realize it immediately.Thanks for your reply again.

Is there a way to add pagination? so we set 100 items, then you scroll to last item and we set next 100 items? and so on

Absolutely, nothing should prevents from only storing in the itemsSource a 100 items, and when you click on next page, change the content to the next 100 items and refresh. This can be useful if the data needs load async or needs a server request for example. We’d recommend to add a loading state to your items and/or scrollview in that case.

1 Like

Ideally i want to avoid next button behaviour and more like twitter or facebook infinite or auto load next 100 items when you reach the last item. This is what something i’d love to be made into list view.

That’s also doable, you can add a range of new items to the itemsSource list when you reach the end of the current content of the scroll view.

Hi! I am doing the same thing.
I am using dynamic height in the listview. When I add a range of new items to the itemsSource list and call the refreshItems function, the order of the items in the listview will be confused unless I call the rebuild function or use fixed height.
Is this a bug?