Blazor WASM Virtualization
Blazor
30 Articles
In this article, let's learn about Virtualization and how to use Virtualize component to load huge data in Blazor WASM application.
Note: If you have not done so already, I recommend you read the article on Blazor WASM App Settings.
Table of Contents
- Why Virtualization?
- When Virtualization?
- Without Virtualization
- With Virtualization
- Virtualize Component
- Item provider delegate
- Placeholder
- Item Size
- Overscan count
- Statechanges
- Summary
Why Virtualization?
Loading a large dataset or displaying data in a grid is a more common way to list data in many applications. Virtualization is a technique for limiting UI rendering to just the parts that are currently visible in UI. This will improve the rendering performance and gives better user experience. For example, virtualization is helpful when the app must render a long list of items and only a subset of items is required to be visible at any given time.
When Virtualization?
Use the Virtualize component when:
- Rendering a set of data items in a loop. For example, loading Recommended Content in I ❤️ .NET
- Most of the items aren't visible due to scrolling.
- The rendered items are the same size.
When the user scrolls to a certain point in the Virtualize component's list of items, the component calculates the visible items to show. Unseen items aren't rendered.
Without Virtualization
Without virtualization, a typical list data might use a C# foreach loop to render each item in a list. In the following example:
- tableOfContents.Contents is a collection of contents.
- The VirtualizationContent displays details about each content.
- The @key directive attribute preserves the relationship of each VirtualizationContent component to its rendered content by the content's ContentId.
Code Sample - Without Virtualization
With Virtualization
If the collection contains thousands of contents, rendering the contents takes a long time and users experience a noticeable UI lag. Most of the contents aren't seen because they fall outside of the height of the <div> element.
Instead of rendering the entire list of contents at once, replace the foreach loop in the preceding example with the Virtualize component:
- Specify tableOfContents.Contents as a fixed item source to Virtualize<TItem>.Items. Only the currently visible contents are rendered by the Virtualize component.
- Specify a context for each content with the Context parameter. In the following example, content is used as the context, which provides access to each content's details.
Code Sample - With Virtualization
If a context isn't specified with the Context parameter, use the value of context in the item content template to access each contents's details:
Virtualize Component
The Virtualize component:
- Calculates the number of items to render based on the height of the container and the size of the rendered items.
- Recalculates and rerenders the items as the user scrolls.
- Only fetches the slice of records from an external API that correspond to the current visible region, instead of downloading all of the data from the collection.
The item content for the Virtualize component can include:
- Plain HTML and Razor code, as the preceding example shows.
- One or more Razor components.
- A mix of HTML/Razor and Razor components.
Item provider delegate
If you don't want to load all of the items into memory, you can specify an items provider delegate method to the component's Virtualize<TItem>.ItemsProvider parameter that asynchronously retrieves the requested items on demand. In the following example, the LoadContents method provides the items to the Virtualize component:
Code Sample - Item Provider Delegate
The items provider receives an ItemsProviderRequest, which specifies the required number of items starting at a specific start index. The items provider then retrieves the requested items from a database or other service and returns them as an ItemsProviderResult<TItem> along with a count of the total items. The items provider can choose to retrieve the items with each request or cache them so that they're readily available.
A Virtualize component can only accept one item source from its parameters, so don't attempt to simultaneously use an items provider and assign a collection to Items. If both are assigned, an InvalidOperationException is thrown when the component's parameters are set at runtime.
Placeholder
Because requesting items from a remote data source might take some time, you have the option to render a placeholder with item content:
Code Sample - Virtualization with Placeholder
- Use a Placeholder (<Placeholder>...</Placeholder>) to display content until the item data is available.
- Use Virtualize<TItem>.ItemContent to set the item template for the list.
Item size
The height of each item in pixels can be set with Virtualize<TItem>.ItemSize (default: 50). By default, the Virtualize component measures the rendering size (height) of individual items after the initial render occurs. Use ItemSize to provide an exact item size in advance to assist with accurate initial render performance and to ensure the correct scroll position for page reloads. If the default ItemSize causes some items to render outside of the currently visible view, a second re-render is triggered. To correctly maintain the browser's scroll position in a virtualized list, the initial render must be correct. If not, users might view the wrong items. The following example changes the height of each item from the default of 50 pixels to 25 pixels:
Code Sample - Virtualization with Item Size
Overscan count
Virtualize<TItem>.OverscanCount determines and controls how many additional items are rendered before and after the visible region. This setting helps to reduce the frequency of rendering during scrolling. However, higher values result in more elements rendered in the page (default: 3). The following example changes the overscan count from the default of three items to four items:
Code Sample - Virtualization with Overscan Count
Statechanges
When making changes to items rendered by the Virtualize component, call StateHasChanged to force re-evaluation and rerendering of the component.
Summary
In this article, we learn't how to use Virtualize component to load huge data without compromising on performance and user experience. We also learn't about Item provider delegate, Placeholder, Item size and Overscan count. The live in browser demo should have helped you to see what is happening in realtime while you scroll.