Virtualize Blazor Component to improve rendering performance and lazy loading with ItemsProvider and Placeholder in ASP.Net Blazor

Views: 128
Comments: 0
Like/Unlike: 1
Posted On: 05-Sep-2024 23:33 

Share:   fb twitter linkedin
Rahul M...
4896 Points
25 Posts


The ASP.NET team recently rolled out Blazor Component Virtualization, a technique for limiting UI rendering to the visible page elements only. You can easily leverage this through a built-in Virtualize component.

Consider a typical scenario where you need to display a large number of items in a table. With thousands of items, users might experience long loading times as the entire dataset is fetched and rendered at once. However, with Blazor component virtualization, the application optimizes performance by initially loading only the records visible within the user's viewport. Additional records are then fetched and rendered dynamically as the user scrolls. In this article, we will demonstrate lazy loading using the .NET delegate technique.

 

Prerequisites

  • .NET 8.0 or greater
  • Visual Studio 2022 or greater


Examples

In this article, we are considering users data with Id, Name, and Address field:

public class User
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
    }

We will see Virtualize control implementation in both way:

  1. Loading Data from In Memory
  2. Loading Data from External API or any service (Lazy Loading) 


Output will look like:


Loading Data from "In Memory"

Runnable code link: https://blazorrepl.telerik.com/meYtYUOg16Vp8FLW41

@page "/virtualization/overview"
@using Microsoft.AspNetCore.Components.Web.Virtualization
<div>
    <table class="table">
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Address</th>
            </tr>
        </thead>
        <tbody>
            <Virtualize Items="@Users"
                        Context="tile" ItemSize="15" OverscanCount="3">
                <ItemContent>
                    <tr>
                        <td>@tile.Id</td>
                        <td>@tile.Name</td>
                        <td>@tile.Address</td>
                    </tr>
                </ItemContent>
                <Placeholder>
                    <p>
                        Loading&hellip;
                    </p>
                </Placeholder>
            </Virtualize>

        </tbody>
    </table>
</div>
@code {
    private List<User> Users;

    protected override async Task OnInitializedAsync()
    {
        Users = await MakeUsers();
    }

    private async Task<List<User>> MakeUsers()
    {
        List<User> users = new List<User>();

        for (int i = 0; i < 10000; i++)
        {
            var car = new User()
                {
                    Id = (i + 1).ToString(),
                    Name = $"Name {(i + 1)}",
                    Address = $"Address {(i + 1)}"
                };
            users.Add(car);
        }
        return await Task.FromResult(users);
    }

    public class User
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
    }
}

 

Loading Data from External API or any service (Lazy Loading) 

Runnable code link: https://blazorrepl.telerik.com/coaNYAYK18RPv16915

@page "/virtualization/overview"
@using Microsoft.AspNetCore.Components.Web.Virtualization
<div>
    <table class="table">
        <thead>
            <tr>
                <th>Id</th>
                <th>Name</th>
                <th>Address</th>
            </tr>
        </thead>
        <tbody>
            <Virtualize ItemsProvider="@LoadUsers"
                        Context="tile" ItemSize="15" OverscanCount="3">
                <ItemContent>
                    <tr>
                        <td>@tile.Id</td>
                        <td>@tile.Name</td>
                        <td>@tile.Address</td>
                    </tr>
                </ItemContent>
                <Placeholder>
                    <p>
                        Loading&hellip;
                    </p>
                </Placeholder>
            </Virtualize>

        </tbody>
    </table>
</div>
@code {

    private async ValueTask<ItemsProviderResult<User>> LoadUsers(ItemsProviderRequest request)
    {
        var users = await MakeUsers();
        await Task.Delay(1000);
        return new ItemsProviderResult<User>(users.Skip(request.StartIndex).Take(request.Count), users.Count());
    }

    private async Task<List<User>> MakeUsers()
    {
        List<User> users = new List<User>();

        for (int i = 0; i < 10000; i++)
        {
            var car = new User()
                {
                    Id = (i + 1).ToString(),
                    Name = $"Name {(i + 1)}",
                    Address = $"Address {(i + 1)}"
                };
            users.Add(car);
        }
        return await Task.FromResult(users);
    }

    public class User
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
    }
}

 

Parameters

  • OverscanCount, we can also set the OverscanCount parameter to control the number of additional items rendered before and after the visible viewport. By default, this value is set to three items. Adjusting this parameter can help prevent excessive rendering and optimize performance, especially when you anticipate extensive scrolling.
  • ItemsDelegate, we can utilize an item provider delegate method. In C#, a delegate is a type that represents methods with a specific parameter list and return type. see in lazy loading example.
  • Placeholder, we can use it show loader for data loading in progress.
  • ItemSize, we can also set the size of each item in pixels, with the default value being 50px.

 

Conclusion

In the above article, we demonstrated two implementations -  rendering data from "in memory" & rendering data on demand from database or api service. Also, we discussed how to perform lazy loading with the ItemsDelegate and Placeholder parameters.

 

0 Comments
 Log In to Chat