Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Virtualize: Analyzing Limitations with Large Datasets #5901

Closed
tesar-tech opened this issue Dec 16, 2024 · 1 comment
Closed

Virtualize: Analyzing Limitations with Large Datasets #5901

tesar-tech opened this issue Dec 16, 2024 · 1 comment
Assignees
Milestone

Comments

@tesar-tech
Copy link
Collaborator

While investigating support for larger datasets ( see) and transitioning from int to long, I identified several issues with the Virtualize component. Below are the findings and potential approaches to address them.

1M large datasets

Even before nearing the int.MaxValue threshold, the Virtualize component begins to exhibit issues with datasets around 1M items.

@page "/"
@using Blazorise.DataGrid
@rendermode  InteractiveServer
<h3>Virtualize in DataGrid</h3>

<DataGrid TItem="LargeModelItem"
          Data="items"
          ReadData="OnDataRead"
          Virtualize="true"
          TotalItems="totalItems"
          
     
>
    <DataGridColumn Field="@nameof( LargeModelItem.Id )" Caption="id" />
    <DataGridColumn Field="@nameof( LargeModelItem.Name )" Caption="Name" Editable/>
</DataGrid>



@code {
    class LargeModelItem
    {
        public long Id { get; set; }
        public string Name { get; set; } = "";
    }

    IEnumerable<LargeModelItem> items = [];
    int totalItems = 10_000_000;
    
    private void OnDataRead(DataGridReadDataEventArgs<LargeModelItem> e)
    {
        items = Enumerable.Range(e.VirtualizeOffset, e.VirtualizeCount).Select(i => new LargeModelItem
        {
            Id = i,
            Name = $"Item id { i} "
        });
    }
}

First you will notice the slider being in half, but it's only on 300k-th item (from 10M):
Image

Second - when you scroll down (by dragging the scrollbar) it lose its marbles and show some "random"... It can get close to 1M, but not in a consistent way.

102d1427-c7c0-4b24-81ae-20d8e95bc595.mp4

This is not an issue with the Blazorise library but rather with browsers themselves. The Virtualize component works by using top and bottom "placeholder" elements, which have their height set to:

numberOfItemsToSkip * heightOfSingleItem

In this case, it results in:

height: 2.73663e+08px;

This value is far too large for browsers to handle, and as a result, they simply cut the content.

It's actually reported in aspnetcore repo: dotnet/aspnetcore#26354
But explained in this answer on SO: https://stackoverflow.com/a/10884837/1154773
With nice too jsfiddle tool to verify the max pixels your browser can handle: https://jsfiddle.net/josh3736/BhHfN/
It is also mentioned in syncfusion's DataGrid docs: https://blazor.syncfusion.com/documentation/datagrid/virtual#limitations-for-virtualization (they don't support such large datasets in virtualized datagrid)

The maximum height for Chromium browsers is 16 million pixels, and for Firefox, it's 4 million pixels. This is why my example fails at around 1 million items, given that each item is approximately 20px in height.

While the issue on the aspnetcore repository was dismissed, I don't believe it's impossible to solve. The scrollbar looks identical whether your list contains 100k items or 10k items—just a small, draggable thumb.

For this reason, I think it is feasible to adapt the Virtualize component to handle much larger datasets. This could be achieved either at the component level or within the Blazorise library itself.

int.MaxValue + datasets

Here it hits another problem.

https://github.com/dotnet/aspnetcore/blob/1f0c1a87709a9b20a46df5c36f616950f0427ad1/src/Components/Web/src/Virtualization/ItemsProviderResult.cs#L20

ItemsProviderResult which is used in:

protected async ValueTask<ItemsProviderResult<TItem>> VirtualizeItemsProviderHandler( ItemsProviderRequest request )

TotalItems is type of int, thus we cannot simply tell it to have more than that.

Solutions?:

  • Just simply mention that in docs "we cannot support large datasets with Virtualize, but it's not our fault"
  • Try to trick the Virtualize to think it's working on something smaller - I think doable, but rabbit holes ahead for sure. "The worst" scenario would be forking the Virtualize component... But from there it would be just a step to make support for int.MaxValue+ datasets - and that would be awesome...
  • Something else ??
@tesar-tech tesar-tech added this to the 2.0 milestone Dec 16, 2024
@stsrki
Copy link
Collaborator

stsrki commented Dec 16, 2024

  • Just simply mention that in docs "we cannot support large datasets with Virtualize, but it's not our fault"

I would do just this. Mention that virtualize will break for >1M of data. It's a technical limitation that is not in our control, so people should understand it.

With long.MaxData, we want to be able to handle non-virtualize mode, which is still possible with regular pagination.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

No branches or pull requests

2 participants