0

Blazor supports virtualization but items need to have same height. For most cases it's okay, but for example for chats where amount of messages can be high and messages have different heights due to word wrapping default blazor Virtualize component is not enough. Is there an easy way to implement virtualization for items with different sizes? I don't care about correct scroll thumb position relative to all items, I can live with thumb tracking only loaded messages.

7
  • No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes. Commented Sep 24 at 8:42
  • You didn't explain what you actually want to do anyway. There may be other components that do what you want. For example this React demo for a Fluent UI 2 DetailsList uses variable-length items. AG-Grid also does this, but renders and buffers rows before they get displayed. Commented Sep 24 at 8:59
  • @PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping. Commented Sep 24 at 11:15
  • @GeorgeKarlinzer You can use Intersection Observer API. Commented Sep 24 at 13:39
  • 1
    "due to word wrapping default blazor Virtualize component is not enough.". Take a look at my quick demo at github.com/ShaunCurtis/SO79773436. [Polite] What am I missing? Commented Sep 24 at 18:24

1 Answer 1

0

It should work. Here's some demo code that shows it working. Blazor Server template with Global Interactivity.

Home with Virtualize:

@page "/"

<PageTitle>Home</PageTitle>

<h1>Hello, world!</h1>

Welcome to your new app.

<Virtualize ItemsProvider="this.GetRows" >
    <div class="m-2 p-2 border border-1">@context.Value</div>
</Virtualize>

@code {
    private ValueTask<ItemsProviderResult<Message>> GetRows(ItemsProviderRequest request) 
        => new(new ItemsProviderResult<Message>( TestDataProvider.Messages.Skip(request.StartIndex).Take(request.Count),TestData.Messages.Count));
}


The data provider

public record Message(string Value);

public static class TestDataProvider
{
    public static readonly List<Message> Messages =
        new()
        {
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("You didn't explain what you actually want to do anyway. There may be other components that do what you want. For example this React demo for a Fluent UI 2 DetailsList uses variable-length items. AG-Grid also does this, but renders and buffers rows before they get displayed"),
            new Message("@IvanStoev thank you very much, that did it. I simply did not notice the existing List of SystemLicenses for Customer, which brought up the problem.. Thanks a lot! "),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("You didn't explain what you actually want to do anyway. There may be other components that do what you want. For example this React demo for a Fluent UI 2 DetailsList uses variable-length items. AG-Grid also does this, but renders and buffers rows before they get displayed"),
            new Message("@IvanStoev thank you very much, that did it. I simply did not notice the existing List of SystemLicenses for Customer, which brought up the problem.. Thanks a lot! "),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("You didn't explain what you actually want to do anyway. There may be other components that do what you want. For example this React demo for a Fluent UI 2 DetailsList uses variable-length items. AG-Grid also does this, but renders and buffers rows before they get displayed"),
            new Message("@IvanStoev thank you very much, that did it. I simply did not notice the existing List of SystemLicenses for Customer, which brought up the problem.. Thanks a lot! "),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("You didn't explain what you actually want to do anyway. There may be other components that do what you want. For example this React demo for a Fluent UI 2 DetailsList uses variable-length items. AG-Grid also does this, but renders and buffers rows before they get displayed"),
            new Message("@IvanStoev thank you very much, that did it. I simply did not notice the existing List of SystemLicenses for Customer, which brought up the problem.. Thanks a lot! "),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("You didn't explain what you actually want to do anyway. There may be other components that do what you want. For example this React demo for a Fluent UI 2 DetailsList uses variable-length items. AG-Grid also does this, but renders and buffers rows before they get displayed"),
            new Message("@IvanStoev thank you very much, that did it. I simply did not notice the existing List of SystemLicenses for Customer, which brought up the problem.. Thanks a lot! "),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("You didn't explain what you actually want to do anyway. There may be other components that do what you want. For example this React demo for a Fluent UI 2 DetailsList uses variable-length items. AG-Grid also does this, but renders and buffers rows before they get displayed"),
            new Message("@IvanStoev thank you very much, that did it. I simply did not notice the existing List of SystemLicenses for Customer, which brought up the problem.. Thanks a lot! "),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("You didn't explain what you actually want to do anyway. There may be other components that do what you want. For example this React demo for a Fluent UI 2 DetailsList uses variable-length items. AG-Grid also does this, but renders and buffers rows before they get displayed"),
            new Message("@IvanStoev thank you very much, that did it. I simply did not notice the existing List of SystemLicenses for Customer, which brought up the problem.. Thanks a lot! "),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("ddddd"),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("@PanagiotisKanavos I want to virtualize chat messages where every message element could have variable height due to word wrapping."),
            new Message("@GeorgeKarlinzer You can use Intersection Observer API. "),
            new Message("No - it it was easy, you wouldn't have to ask for it. UI virtualization works by replacing placeholders with data. You need to know the size of the placeholder in advance. The perf benefits come because the page doesn't have to create or destroy elements, or recompute the layout due to changing sizes."),
            new Message("You didn't explain what you actually want to do anyway. There may be other components that do what you want. For example this React demo for a Fluent UI 2 DetailsList uses variable-length items. AG-Grid also does this, but renders and buffers rows before they get displayed"),
        };
}
Sign up to request clarification or add additional context in comments.

3 Comments

Does this work if the first 10-20 items are small ones? I actually checked the source code when commenting. The component creates placeholders with a specific size. Although I admit I took the OP's word that the display isn't working properly and didn't test it.
I didn't actually try, I just put together the demo as a starting point to see what was happening. You probably need to optimize OverscanCount to get it right.
If you try and scroll a large dataset with variable size items, it will cause a mess, especially on a laggy connections. You may get away with it with small data amounts.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.