Optimizing Blazor TreeView Performance with Virtualization
Tags: blazor, treeview, ui, web
Published: 2024-07-17 16:55:17

---
title: Optimizing Blazor TreeView Performance with Virtualization
published: true
date: 2024-07-04 12:32:21 UTC
tags: blazor, treeview, ui, web
canonical_url: https://www.syncfusion.com/blogs/post/blazor-treeview-virtualization
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hln9fs1mtg69x37wub2a.png
---
**TL;DR:** Enhance the performance of the Syncfusion Blazor TreeView component with the new virtualization feature added in the 2024 volume 2 release. Learn how to implement and benefit from this feature!

Syncfusion [Blazor TreeView](https://www.syncfusion.com/blazor-components/blazor-treeview "Blazor TreeView component") is a UI component that displays hierarchical data such as a table of contents, code examples, and file directories in a tree-like structure. It is a feature-rich component, supporting data binding, load-on-demand, multiple selection, drag and drop, node editing, checkboxes, templates, and more in both Blazor WebAssembly (WASM) and Blazor Server apps.

The load-on-demand (lazy-load) feature is enabled by default to reduce bandwidth usage when consuming large amounts of data. Only first-level nodes are loaded initially, and then child nodes are loaded when their parent node is expanded.

If a parent node has multiple sub-levels of child nodes, the load-on-demand feature will load only the child nodes of the corresponding parent when expanded. In this scenario, the child nodes of collapsed parent nodes will not be loaded.

However, in cases where a large number of parent nodes are rendered, or a single parent node with many child nodes is rendered, a more efficient solution than the load-on-demand feature is needed. This is where [virtualization](https://blazor.syncfusion.com/documentation/treeview/virtualization "Virtualization in Blazor TreeView component") becomes essential.

## Virtualization

Virtualization involves rendering nodes for the current viewport alone and avoiding rendering off-screen items. This technique ensures optimal performance when dealing with huge datasets.    

The Blazor TreeView’s UI virtualization dynamically loads the nodes when the user scrolls the container scroller. The virtualization process is intelligently managed based on the [Height](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Navigations.SfTreeView-1.html#Syncfusion_Blazor_Navigations_SfTreeView_1_Height "Height property of Blazor TreeView component") property of the TreeView component. This support has been included in the latest [Essential Studio 2024 Volume 2](https://www.syncfusion.com/forums/188642/essential-studio-2024-volume-2-main-release-v26-1-35-is-available-for-download "Essential Studio 2024 Volume 2") release.

This blog will examine virtualization’s benefits and how to implement it in the Blazor TreeView component.

## Benefits of virtualization

Let’s explore the benefits that virtualization brings to the Blazor TreeView component!

### Addressing performance challenges

Dealing with a multitude of DOM elements often leads to performance challenges. Browser engines may struggle to manage large DOM structures effectively, even when a component optimizes data. The challenge lies in ensuring seamless webpage performance while interacting with many DOM elements.

In Blazor TreeView, the UI [virtualization](https://blazor.syncfusion.com/demos/treeview/ui-virtualization?theme=fluent "Virtualization in Blazor TreeView component demos") feature comes into play when you need to display thousands of nodes in a single TreeView. Initially, the component retrieves the entire data source for the component and renders only the number of nodes that adapt to the current viewport. The rest of the nodes will be loaded on demand through scrolling. Keyboard scrolling is supported as well.

### Reducing initial loading time

Virtualization also helps us reduce the time taken for the initial rendering of the Blazor TreeView component bound to a large data set, which will speed up the app.

## Steps to enable virtualization in Blazor TreeView

Follow these steps to enable the virtualization feature in the Blazor TreView component:

1.First, render the TreeView component in your Blazor app with the required data source, as per the [getting started documentation](https://blazor.syncfusion.com/documentation/treeview/getting-started "Getting started with Blazor TreeView component"). 
2.Refer to this [documentation](https://blazor.syncfusion.com/documentation/treeview/data-binding "Data binding in Blazor TreeView component"), to know the data binding types supported in the Blazor TreeView.
3.Finally, enable the virtualization feature in the Blazor TreeView by setting the [EnableVirtualization](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Navigations.SfTreeView-1.html#Syncfusion_Blazor_Navigations_SfTreeView_1_EnableVirtualization "EnableVirtualization property of Blazor TreeView component") property to **true**. Refer to the following code example.
```xml
@using Syncfusion.Blazor.Navigations
@using Syncfusion.Blazor.Data

<div class="control_wrapper">
 @*Initialize the TreeView component*@
  <SfTreeView TValue="NodeResult" EnableVirtualization=true Height="400px">
    <TreeViewFieldsSettings TValue="NodeResult" Id="Id" Text="Name" ParentID="Pid" HasChildren="HasChild" Expanded="Expanded" Query="TreeViewQuery TreeViewQuery ">
      <SfDataManager Url="api/Nodes" CrossDomain="true" Adaptor="Syncfusion.Blazor.Adaptors.WebApiAdaptor"></SfDataManager>
    </TreeViewFieldsSettings>
    <TreeViewTemplates TValue="NodeResult">
      <NodeTemplate>
        <div>@context.Name</div>
      </NodeTemplate>
    </TreeViewTemplates>
  </SfTreeView>
</div>

@code {
  public Query TreeViewQuery = new Query();
   public class NodeResult
   {
      public int? Id { get; set; }
      public string Name { get; set; }
      public int? Pid { get; set; }
      public bool HasChild { get; set; }
      public bool Expanded { get; set; }
      public bool Checked { get; set; }
      public bool Selected { get; set; }
   }

}
```
Refer to the code for the Web API controller.
```csharp
using Microsoft.AspNetCore.Mvc;
 
namespace TreeView.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class NodesController : ControllerBase
    {
        [HttpGet]
        public IEnumerable<NodeResult> Get()
        {
            var queryString = Request.Query;
            if (queryString.Keys.Contains("$filter"))
            {
                // Load the child data based on the expanded parent.
                string filter = string.Join("", queryString["$filter"].ToString().Split(' ').Skip(2)); // Get filter from querystring.
                int parentId = int.Parse(filter);
                List<NodeResult> TreeViewData = GetItemsFromId(parentId);
                return TreeViewData;
            }
            else
            {
                // Get first-level tree data alone during the initial rendering.
                return GetRootData();
            }
        }
 
        private static List<NodeResult> GetRootData()
        {
            return new List<NodeResult>()
            {
                new NodeResult() { Id = 1, Name = "Software Developers", HasChild = true, Expanded = true,Checked = false, Selected= true },
                new NodeResult() { Id = 2, Name = "UX/UI Designers", HasChild = true, Expanded = false,Checked = false, Selected= true },
                new NodeResult() { Id = 3, Name = "Quality Testers", HasChild = true, Expanded = false,Checked = false, Selected= true },
                new NodeResult() { Id = 4, Name = "Technical Support", HasChild = true, Expanded = false,Checked = false, Selected= true },
                new NodeResult() { Id = 5, Name = "Network Engineers", HasChild = true, Expanded = false,Checked = false, Selected= true }
            };
        }
 
        private List<NodeResult> GetItemsFromId(int id)
        {
            List<NodeResult> DefaultData = new List<NodeResult>()
            {
                new NodeResult() { Name = "Nancy" },
                new NodeResult() { Name = "Andrew" },
                new NodeResult() { Name = "Janet" },
                new NodeResult() { Name = "Margaret" },
                new NodeResult() { Name = "Steven" },
                new NodeResult() { Name = "Laura" },
                new NodeResult() { Name = "Robert" },
                new NodeResult() { Name = "Michael" },
                new NodeResult() { Name = "Albert" },
                new NodeResult() { Name = "Nolan" },
                new NodeResult() { Name = "Jennifer" },
                new NodeResult() { Name = "Carter" },
                new NodeResult() { Name = "Allison" },
                new NodeResult() { Name = "John" },
                new NodeResult() { Name = "Susan" },
                new NodeResult() { Name = "Lydia" },
                new NodeResult() { Name = "Kelsey" },
                new NodeResult() { Name = "Jessica" },
                new NodeResult() { Name = "Shelley" },
                new NodeResult() { Name = "Jack" }
            };
 
            int count = 10000 * id;
            List<NodeResult> TreeViewData = Enumerable.Range(0, 2000)
            .Select(j =>
            {
                count++;
                return new NodeResult { Id = count, Name = DefaultData[j % DefaultData.Count].Name + " - " + count.ToString(), Pid = id, Checked = false, Selected = true };
            }).ToList();
            return TreeViewData;
        }
 
        public class NodeResult
        {
            public int? Id { get; set; }
            public string Name { get; set; }
            public int? Pid { get; set; }
            public bool HasChild { get; set; }
            public bool Expanded { get; set; }
            public bool Checked { get; set; }
            public bool Selected { get; set; }
        }
 
    }
 }
```
  
Refer to the following GIF image demonstrating the seamless loading of nodes in the Blazor TreeView component.
<figure>

  <img src="https://www.syncfusion.com/blogs/wp-content/uploads/2024/07/Implementing-virtualization-in-the-Blazor-TreeView-component.gif" alt="Implementing virtualization in the Blazor TreeView component" style="width:100%">

  <figcaption>Implementing virtualization in the Blazor TreeView component</figcaption>

</figure>

## Performance metrics

Let’s see the performance difference between the TreeView rendered with and without virtualization on the Blazor server and WebAssembly (WASM) apps. This is the status as per the 2024 Volume 2 release.
<table style="width: 100%;" width="624">
<tbody>
<tr>
<td style="width: 23.4524%;" width="184">
<p><strong>Nodes count</strong></p>
</td>
<td style="width: 19.8809%;" width="109">
<p><strong>Server</strong> <strong>without virtualization</strong></p>
</td>
<td style="width: 17.381%;" width="108">
<p><strong>Server with virtualization</strong></p>
</td>
<td style="width: 18.9285%;" width="118">
<p><strong>WASM without virtualization</strong></p>
</td>
<td style="width: 18.5715%;" width="105">
<p><strong>WASM with virtualization</strong></p>
</td>
</tr>
<tr>
<td style="width: 23.4524%;" width="184">
<p>10 k data</p>
</td>
<td style="width: 19.8809%;" width="109">
<p>40730 ms&nbsp;</p>
</td>
<td style="width: 17.381%;" width="108">
<p>920 ms&nbsp;</p>
</td>
<td style="width: 18.9285%;" width="118">
<p>120000 ms&nbsp;</p>
</td>
<td style="width: 18.5715%;" width="105">
<p>7750 ms&nbsp;</p>
</td>
</tr>
<tr>
<td style="width: 23.4524%;" width="184">
<p>10 K data (All nodes are selected and rendered using templates)</p>
</td>
<td style="width: 19.8809%;" width="109">
<p>90000 ms</p>
</td>
<td style="width: 17.381%;" width="108">
<p>950 ms&nbsp;</p>
</td>
<td style="width: 18.9285%;" width="118">
<p>138000 ms&nbsp;</p>
</td>
<td style="width: 18.5715%;" width="105">
<p>8400 ms&nbsp;</p>
</td>
</tr>
</tbody>
</table>

The above table proves that the virtualization feature considerably enhances the performance of the Blazor TreeView.

## References

For more details, refer to the [Virtualization in Blazor TreeView demo](https://blazor.syncfusion.com/demos/treeview/ui-virtualization?theme=fluent "Virtualization in Blazor TreeView demo") and [documentation](https://blazor.syncfusion.com/documentation/treeview/virtualization "Virtualization in Blazor TreeView documentation"). 

## Conclusion

Thanks for reading! This article provides a clear and straightforward guide for implementing virtualization in the [Blazor TreeView](https://www.syncfusion.com/blazor-components/blazor-treeview "Blazor TreeView") component. We hope you found it helpful. If you have any questions, feel free to share them in the comments section below.

You can also check out all the other features rolled out in the [2024 volume 2](https://www.syncfusion.com/forums/188642/essential-studio-2024-volume-2-main-release-v26-1-35-is-available-for-download "Essential Studio 2024 Volume 2") release on our [Release Notes](https://help.syncfusion.com/common/essential-studio/release-notes/v26.1.35 "Essential Studio Release Notes") and [What’s New](https://www.syncfusion.com/products/whatsnew "Essential Studio What’s New page") pages.

Try out these features and share your feedback as comments on this blog. You can also reach us through our [support forums](https://www.syncfusion.com/forums "Syncfusion Support Forum"), [support portal](https://support.syncfusion.com/ "Syncfusion Support Portal"), or [feedback portal](https://www.syncfusion.com/feedback/ "Syncfusion Feedback Portal").

## Related blogs

- [Syncfusion Essential Studio 2024 Volume 2 Is Here!](https://www.syncfusion.com/blogs/post/syncfusion-essential-studio-2024-vol2 "Blog: Syncfusion Essential Studio 2024 Volume 2 Is Here!")
- [What’s New in Blazor: 2024 Volume 2](https://www.syncfusion.com/blogs/post/whats-new-blazor-2024-volume-2 "Blog: What’s New in Blazor: 2024 Volume 2")
- [What’s New in Blazor Diagram: 2024 Volume 2](https://www.syncfusion.com/blogs/post/whats-new-blazor-diagram-2024-vol-2 "Blog: What’s New in Blazor Diagram: 2024 Volume 2")
- [Introducing the New Blazor OTP Input Component](https://www.syncfusion.com/blogs/post/new-blazor-otp-input-component "Blog: Introducing the New Blazor OTP Input Component")