From 56ae5b55b5d323c863c9564b2b2150a1078e4bc9 Mon Sep 17 00:00:00 2001
From: Dimo Dimov <961014+dimodi@users.noreply.github.com>
Date: Fri, 7 Mar 2025 15:09:31 +0200
Subject: [PATCH 1/7] docs(Grid,TreeList): Revamp Virtual Scrolling
documentation
---
components/grid/manual-operations.md | 18 +-
components/grid/virtual-scrolling.md | 346 +++++-------------
components/treelist/virtual-scrolling.md | 180 ++++++---
.../grid-hide-virtual-row-skeletons.md | 88 +++++
knowledge-base/grid-reduce-row-height.md | 115 ++++++
.../grid-virtual-scrolling-not-working.md | 8 +-
.../grid-virtualization-many-records.md | 55 +--
7 files changed, 479 insertions(+), 331 deletions(-)
create mode 100644 knowledge-base/grid-hide-virtual-row-skeletons.md
create mode 100644 knowledge-base/grid-reduce-row-height.md
diff --git a/components/grid/manual-operations.md b/components/grid/manual-operations.md
index ecb68ecfb8..b5dfb96bec 100644
--- a/components/grid/manual-operations.md
+++ b/components/grid/manual-operations.md
@@ -29,6 +29,7 @@ Examples:
* [Telerik .ToDataSourceResult(request)](#telerik-todatasourceresult-request)
* [Grouping with OnRead](#grouping-with-onread)
* [Aggregates with OnRead](#aggregates-with-onread)
+* [Virtual Scrolling with OnRead](#virtual-scrolling-with-onread)
* [Get Information From the DataSourceRequest](#get-information-from-the-datasourcerequest)
* [Use OData Service](https://github.com/telerik/blazor-ui/tree/master/grid/odata)
* [Serialize the DataSoureRequest to the server](https://github.com/telerik/blazor-ui/tree/master/grid/datasourcerequest-on-server)
@@ -277,9 +278,7 @@ This sample shows how to set up the grid to use grouping with manual data source
When using [aggregates](slug:grid-aggregates) with `OnRead`, the Grid expects you to set one more property of the `GridReadEventArgs` object - `AggregateResults`. Otherwise the component will show aggregate values for the current page only.
-
-
-````CS
+````C#.skip-repl
private async Task OnGridRead(GridReadEventArgs args)
{
DataSourceResult result = AllGridData.ToDataSourceResult(args.Request);
@@ -290,6 +289,19 @@ private async Task OnGridRead(GridReadEventArgs args)
}
````
+## Virtual Scrolling with OnRead
+
+When using [virtual Grid scrolling](slug:components/grid/virtual-scrolling), get the values of `args.Request.Skip` and `args.Request.PageSize` to determine the current Grid scroll offset and load the correct data items. Do not use `args.Request.Page` with virtual scrolling, because it is always `1`.
+
+````C#.skip-repl
+private List GridData { get; set; } = new();
+
+private async Task OnGridRead(GridReadEventArgs args)
+{
+ args.Data = GridData.Skip(args.Request.Skip).Take(args.Request.PageSize);
+ args.Total = GridData.Count;
+}
+````
## Get Information From the DataSourceRequest
diff --git a/components/grid/virtual-scrolling.md b/components/grid/virtual-scrolling.md
index ab577019e2..25041c6424 100644
--- a/components/grid/virtual-scrolling.md
+++ b/components/grid/virtual-scrolling.md
@@ -8,281 +8,134 @@ published: True
position: 60
---
-# Virtual Scrolling
+# Grid Virtual Scrolling
-Virtual scrolling provides an alternative to paging. Instead of utilizing a pager, the user scrolls vertically through all records in the data source.
+Virtual Grid scrolling allows users to scroll vertically through all records in the Grid data source. The feature is an alternative to paging.
-To enhance rendering performance, the Grid reuses the same set of HTML elements. As the next data loads, a loading indicator appears on the cells. If the user scrolls back up after scrolling down to the next set of rows, the previous data reloads from the data source, similar to regular paging, with the scroll distance determining the data to be loaded.
+To enhance the rendering performance, the Grid reuses the same set of HTML elements. Loading indicators (skeletons) appear in the table cells during scrolling and data loading. If the user scrolls back up after scrolling down to the next set of rows, the previous data reloads from the data source, similar to regular paging, with the scroll distance determining the data to be loaded.
-You can also use the Blazor Grid virtualization for the Grid columns. See the [Column Virtualization](slug:grid-columns-virtual) article for more information.
+You can also use the [Blazor Grid virtualization for the Grid columns](slug:grid-columns-virtual).
## Using Virtual Scrolling
-For the Blazor Grid virtualization to work, you need to:
+To enable Blazor Grid row virtualization:
1. Set the `ScrollMode` parameter to `GridScrollMode.Virtual` (the default value is `Scrollable`).
-1. [Set the `Height` parameter](#setting-a-value-for-the-height-parameter).
-1. [Set the `RowHeight` parameter](#setting-a-value-for-the-rowheight-parameter).
-1. [Set the `PageSize` parameter](#setting-a-value-for-the-pagesize-parameter).
+1. [Set the `Height` parameter](#height) to a `string` CSS value.
+1. [Set the `RowHeight` parameter](#rowheight) to a `decimal` value that denotes pixels.
+1. [Set the `PageSize` parameter](#pagesize).
-## Setting a Value for the Height Parameter
+> The values of the `Height`, `RowHeight`, and `PageSize` parameters are related to one another. The following sections explain how.
-Set the `Height` parameter to a `string` value. The value can be in:
+## Height
-* Pixels—for example, `Height="480px"`.
-* Percent—for example, `Height="30%"`. If you set the `Height` parameter to a percentage value, ensure that the wrapper of the Grid has a fixed height set in pixels.
-* Relative CSS units like vh, vmin, and vmax—for example, `Height="30vh"`.
+Set the Grid `Height` parameter to any [valid `string` CSS value](slug:common-features/dimensions), for example, `px`, `%`, `em`, or `vh`. If the Grid should expand vertically, accoding to the available space, then check the article [Adjust Grid Height to Match the Browser Viewport Height](slug:grid-kb-adjust-height-with-browser).
-The tabs below show how to set the `Height` parameter with the different value options.
+Set the `Height` value, so that users can't see the whole [`PageSize` of items](#pagesize) at once. Otherwise, empty row skeletons may display in the Grid while users are not scrolling.
-
-````RAZOR Pixel
-@using Telerik.DataSource
-@using Telerik.DataSource.Extensions
-
-
-
-
-
-
-
-
-@code {
- private List GridData { get; set; } = new List();
-
- private async Task OnGridRead(GridReadEventArgs args)
- {
- await Task.Delay(200); // simulate network delay
+## PageSize
- DataSourceResult result = GridData.ToDataSourceResult(args.Request);
-
- args.Data = result.Data;
- args.Total = result.Total;
- args.AggregateResults = result.AggregateResults;
- }
+Set the Grid `PageSize` parameter to an `int` value. The `PageSize` determines:
- protected override void OnInitialized()
- {
- GridData = new List();
- var rnd = new Random();
+* How many table rows are populated and rendered at any given time.
+* How many data items are requested from the data source when using the [Grid `OnRead` event to load data on demand](slug:components/grid/manual-operations).
- for (int i = 1; i <= 1000; i++)
- {
- GridData.Add(new Product()
- {
- Id = i,
- Name = $"Product {i}",
- Stock = rnd.Next(0, 100)
- });
- }
- }
+Set the `PageSize` value, so that the rendered table rows do fit in the [Grid height](#height). At least one table row must be completely invisible.Otherwise, empty row skeletons may display in the Grid while users are not scrolling. The exact `PageSize` value allows you to balance between better user experience and data request efficiency:
- public class Product
- {
- public int Id { get; set; }
- public string Name { get; set; } = string.Empty;
- public int Stock { get; set; }
- }
-}
-````
-````RAZOR Percent
-@using Telerik.DataSource
-@using Telerik.DataSource.Extensions
+* A larger `PageSize` value will make the Grid display empty row skeletons more rarely while users are scrolling down. At the same time, the Grid may be requesting a larger number of data items repetitively.
+* A smaller `PageSize` will make the Grid request a smaller number of items on each user scroll. At the same time, users will see row skeletons sooner or more frequently during scrolling.
-
-
-
-
-
-
-
-
+> The `PageSize` value does not affect the data request frequency. The Grid `OnRead` event always fires when the user stops scrolling, no matter what data is currently available.
-@code {
- private List GridData { get; set; } = new List();
+## RowHeight
- private async Task OnGridRead(GridReadEventArgs args)
- {
- await Task.Delay(200); // simulate network delay
+Set the `RowHeight` parameter to a `decimal` value. The Grid uses it to set an inline `height` style in pixels to all Grid table rows (``).
- DataSourceResult result = GridData.ToDataSourceResult(args.Request);
+The `RowHeight` value must be large enough to accommodate the cell content in all rows, even if the content differs. In other words, the `RowHeight` setting must apply the same or greater table row height than what the browser would normally render. The effective row height depends on:
- args.Data = result.Data;
- args.Total = result.Total;
- args.AggregateResults = result.AggregateResults;
- }
+* The cell content and text wrapping.
+* The [`Size` parameter value](slug:grid-sizing).
+* The CSS theme, including font size, line height, and cell paddings.
- protected override void OnInitialized()
- {
- GridData = new List();
- var rnd = new Random();
+For example, the following list shows the minimum valid `RowHeight` values when using the [built-in CSS themes](slug:themes-overview), single-line plain text content, no command buttons, and [`Medium` `Size`](slug:grid-sizing):
- for (int i = 1; i <= 1000; i++)
- {
- GridData.Add(new Product()
- {
- Id = i,
- Name = $"Product {i}",
- Stock = rnd.Next(0, 100)
- });
- }
- }
+* `36` for the Default theme (`14px` font size, `20px` line height, and 2 * `8px` vertical paddings)
+* `40` for the Bootstrap theme (`16px` font size, `24px` line height, and 2 * `8px` vertical paddings)
+* `48` for the Material theme (`14px` font size, `28px` line height, and 2 * `10px` vertical paddings)
+* `44` for the Fluent theme (`14px` font size, `20px` font size and 2 * `12px` vertical paddings)
- public class Product
- {
- public int Id { get; set; }
- public string Name { get; set; } = string.Empty;
- public int Stock { get; set; }
- }
-}
-````
-````RAZOR RelativeUnits
-@using Telerik.DataSource
-@using Telerik.DataSource.Extensions
+> Browsers treat table row `height` styles as `min-height` styles. If the table row content cannot fit in the set `RowHeight`, the browser expands the table row. The Grid configuration must not allow this to happen. It is crucial that all Grid table rows display with the same effective height when using virtial scrolling, otherwise the virtual scrolling experience will break.
-Select a relative CSS unit from the RadioGroup to see how the Grid's Height reacts to different relative CSS units.
+The `RowHeight` parameter value cannot change at runtime, unless the application recreates the whole Grid component by removing it from the web page temporarily.
-
-
+If necessary, you can also use the `RowHeight` parameter without virtual row scrolling.
-
-
-
-
-
-
-
-@code {
- private int ChosenRelativeUnit { get; set; }
-
- private string GridHeight { get; set; }
-
- private void RadioGroupChanged(int relativeUnitId)
- {
- ChosenRelativeUnit = relativeUnitId;
-
- RelativeUnitsDescriptor relativeUnit = RelativeUnitsOptions.FirstOrDefault(x => x.RelativeUnitId == relativeUnitId);
-
- GridHeight = "50" + relativeUnit.RelativeUnitText;
- }
-
- private async Task OnGridRead(GridReadEventArgs args)
- {
- await Task.Delay(200); // simulate network delay
-
- DataSourceResult result = GridData.ToDataSourceResult(args.Request);
-
- args.Data = result.Data;
- args.Total = result.Total;
- args.AggregateResults = result.AggregateResults;
- }
-
- protected override void OnInitialized()
- {
- GridHeight = "50" + RelativeUnitsOptions.FirstOrDefault().RelativeUnitText;
-
- GridData = new List();
-
- var rnd = new Random();
-
- for (int i = 1; i <= 1000; i++)
- {
- GridData.Add(new Product()
- {
- Id = i,
- Name = $"Product {i}",
- Stock = rnd.Next(0, 100)
- });
- }
- }
-
- private List GridData { get; set; } = new List();
+## Limitations
- private List RelativeUnitsOptions { get; set; } = new List
- {
- new RelativeUnitsDescriptor { RelativeUnitId = 1, RelativeUnitText = "vm" },
- new RelativeUnitsDescriptor { RelativeUnitId = 2, RelativeUnitText = "vmax" },
- new RelativeUnitsDescriptor { RelativeUnitId = 3, RelativeUnitText = "vmin" }
- };
+The Blazor Grid virtualization enhances client-side rendering performance and improves the user experience by providing quicker access to all data items. However, this comes with the trade-offs:
- public class Product
- {
- public int Id { get; set; }
- public string Name { get; set; } = string.Empty;
- public int Stock { get; set; }
- }
+* [Hierarchy](slug:components/grid/features/hierarchy) is not supported. If the Grid hierarchy is self-referencing, use a [TreeList with virtual scrolling](slug:treelist-virtual-scrolling) instead.
+* [Grouping](slug:components/grid/features/grouping) is supported only when [loading groups on demand](slug:grid-group-lod).
+* There is a [browser limitation, which affects the maximum number of data items in a virtual Grid](slug:grid-kb-virtualization-many-records). The problem occurs with millions of items and you can partially mitigate it by [changing the Grid styles to make the row height smaller](slug:grid-kb-reduce-row-height).
- public class RelativeUnitsDescriptor
- {
- public int RelativeUnitId { get; set; }
- public string RelativeUnitText { get; set; }
- }
-}
-````
+In addition to virtual scrolling, another approach to optimize the app rendering and data request performance is to use [Grid paging](slug:components/grid/features/paging) and [`OnRead` event](slug:common-features-data-binding-onread).
-## Setting a Value for the RowHeight Parameter
+## Example
-Set the `RowHeight` parameter to a `decimal` value which will always be interpreted as pixels (`px`). The value of the `RowHeight` must be greater than the height of the cell (or row) that the browser would normally render.
+Row virtualization is often used with a large number of data items that cannot be loaded in a single request. Thus, the example below uses the [Grid `OnRead` event](slug:components/grid/manual-operations) together with the [`ToDataSourceResultAsync()`](slug:common-features-data-binding-onread#todatasourceresult-method) method. You can also use the Grid `Data` parameter and load all data items with a single request. [Do not use `Data` and `OnRead` at the same time](slug:common-features-data-binding-overview#how-to-provide-data).
-Consider the following specifics when setting the row height value:
+If you use the `OnRead` event without `ToDataSourceResultAsync()`, then [use the `Skip` and `PageSize` values](slug:components/grid/manual-operations#virtual-scrolling-with-onread) of the [`DataSourceRequest` argument](slug:common-features-data-binding-onread#event-argument) to determine the Grid scroll offset and load the correct data items.
-* The Grid renders padding in the cells by default. The loading skeletons have a line height in order to render. This results in some minimum row heights, which can vary depending on the theme and custom CSS styles on the page.
-* Ensure the height of the `td` element matches the `RowHeight` when using the [Row Template](slug:grid-templates-row).
-* Do not change the value of the `RowHeight` parameter at runtime.
+>caption Virtual Grid scrolling with optional OnRead event and grouping
````RAZOR
-@* Remove the default padding and margin from the cells and remove the default line height of the loading skeletons to reduce the row height. *@
-
@using Telerik.DataSource
@using Telerik.DataSource.Extensions
-
-
+ Sortable="true">
+
+
+
-
-
+
+
+ Count: @context.Count
+
+
+
+
+
+
+ DataSourceRequest.Skip
value
+ in the OnRead
event argument: @GridSkip
+
+
@code {
- private List GridData { get; set; } = new List();
+ private List GridData { get; set; } = new();
+
+ private int GridSkip { get; set; }
private async Task OnGridRead(GridReadEventArgs args)
{
- await Task.Delay(200); // simulate network delay
+ // Use args.Request.Skip and args.Request.PageSize
+ // to load the correct data items without ToDataSourceResultAsync()
+ GridSkip = args.Request.Skip;
- DataSourceResult result = GridData.ToDataSourceResult(args.Request);
+ DataSourceResult result = await GridData.ToDataSourceResultAsync(args.Request);
args.Data = result.Data;
args.Total = result.Total;
@@ -291,17 +144,18 @@ Consider the following specifics when setting the row height value:
protected override void OnInitialized()
{
- GridData = new List();
- var rnd = new Random();
-
for (int i = 1; i <= 1000; i++)
{
GridData.Add(new Product()
- {
- Id = i,
- Name = $"Product {i}",
- Stock = rnd.Next(0, 100)
- });
+ {
+ Id = i,
+ Name = $"Name {i}",
+ Category = $"Category {i % 6 + 1}",
+ Price = Random.Shared.Next(1, 100) * 1.23m,
+ Quantity = Random.Shared.Next(0, 1000),
+ Release = DateTime.Now.AddDays(-Random.Shared.Next(60, 1000)),
+ Discontinued = i % 4 == 0
+ });
}
}
@@ -309,31 +163,17 @@ Consider the following specifics when setting the row height value:
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
- public int Stock { get; set; }
+ public string Category { get; set; } = string.Empty;
+ public decimal Price { get; set; }
+ public int Quantity { get; set; }
+ public DateTime Release { get; set; }
+ public bool Discontinued { get; set; }
}
}
````
-## Setting a Value for the PageSize Parameter
-
-Set the `PageSize` parameter to an `int` value. The `PageSize` determines how many rows are rendered at any given time and how many items are requested from the data source when loading data on demand. For optimal performance, use a page size that fills the grid's data viewport without being excessively large.
-
-## Limitations
-
-The Blazor Grid virtualization primarily enhances client-side rendering performance and improves the user experience. However, it comes with the trade-off that certain features of the Grid are incompatible with it. An alternative approach is to utilize [regular paging](slug:components/grid/features/paging) combined with [manual data source operations](slug:components/grid/manual-operations) to achieve the desired data retrieval performance.
-
-These are the known limitations of the virtual scrolling feature:
-
-* [Hierarchy](slug:components/grid/features/hierarchy) is not supported.
-
-* [Grouping](slug:components/grid/features/grouping) is not supported. [Loading Group Data On Demand](slug:grid-group-lod) is supported, however.
-
-
## See Also
- * [Live Demo: Grid Virtual Scrolling](https://demos.telerik.com/blazor-ui/grid/virtual-scrolling)
- * [Selection in Grid with Virtualized Rows](slug:grid-selection-row#selection-and-virtual-scrolling)
- * [Knowledge Base Article: Virtual Scroll Does Not Show All Items](slug:grid-kb-virtualization-many-records)
- * [Knowledge Base Article: Virtual Scrolling Does Not Work](slug:grid-kb-virtual-scrolling-troubleshooting)
- * [Knowledge Base Article: Setting Too Large Skip](slug:grid-kb-large-skip-virtualization)
- * [Blazor Grid](slug:grid-overview)
+* [Live Demo: Grid Virtual Scrolling](https://demos.telerik.com/blazor-ui/grid/virtual-scrolling)
+* [Grid Selection with Virtual Rows](slug:grid-selection-row#selection-and-virtual-scrolling)
+* [How to Disable Row Placeholders During Virtual Scrolling](slug:grid-kb-hide-virtual-row-skeletons)
diff --git a/components/treelist/virtual-scrolling.md b/components/treelist/virtual-scrolling.md
index ba266651ef..056ac86c40 100644
--- a/components/treelist/virtual-scrolling.md
+++ b/components/treelist/virtual-scrolling.md
@@ -3,93 +3,179 @@ title: Virtual Scrolling
page_title: TreeList - Virtual Scrolling
description: Enable and configure the virtual scrolling of rows in the TreeList for Blazor.
slug: treelist-virtual-scrolling
-tags: telerik,blazor,treelist,virtual,rows,scrolling
+tags: telerik,blazor,treelist,virtual,scrolling
published: True
position: 25
---
# TreeList Virtual Scrolling
+Virtual TreeList scrolling allows users to scroll vertically through all records in the TreeList data source. The feature is an alternative to paging.
-Virtual scrolling provides an alternative to paging. Instead of utilizing a pager, the user scrolls vertically through all records in the data source.
+To enhance the rendering performance, the TreeList reuses the same set of HTML elements. Loading indicators (skeletons) appear in the table cells during scrolling and data loading. If the user scrolls back up after scrolling down to the next set of rows, the previous data reloads from the data source, similar to regular paging, with the scroll distance determining the data to be loaded.
-To enhance rendering performance, the TreeList reuses the same set of HTML elements. As the next data loads, a loading indicator appears on the cells. If the user scrolls back up after scrolling down to the next set of rows, the previous data reloads from the data source, similar to regular paging, with the scroll distance determining the data to be loaded.
+You can also use the [Blazor TreeList virtualization for the TreeList columns](slug:treelist-columns-virtual).
## Using Virtual Scrolling
-* Set the `ScrollMode` parameter to `TreeListScrollMode.Virtual` (the default value is `Scrollable`).
-* Set the `Height` and `RowHeight` parameters.
+To enable Blazor TreeList row virtualization:
->caption Enable virtual scrolling in the Telerik TreeList for Blazor
+1. Set the `ScrollMode` parameter to `TreeListScrollMode.Virtual` (the default value is `Scrollable`).
+1. [Set the `Height` parameter](#height) to a `string` CSS value.
+1. [Set the `RowHeight` parameter](#rowheight) to a `decimal` value that denotes pixels.
+1. [Set the `PageSize` parameter](#pagesize).
+
+> The values of the `Height`, `RowHeight`, and `PageSize` parameters are related to one another. The following sections explain how.
+
+## Height
+
+Set the TreeList `Height` parameter to any [valid `string` CSS value](slug:common-features/dimensions), for example, `px`, `%`, `em`, or `vh`. If the TreeList should expand vertically, accoding to the available space, then check the article [Adjust Grid Height to Match the Browser Viewport Height](slug:grid-kb-adjust-height-with-browser).
+
+Set the `Height` value, so that users can't see the whole [`PageSize` of items](#pagesize) at once. Otherwise, empty row skeletons may display in the TreeList while users are not scrolling.
+
+## PageSize
+
+Set the TreeList `PageSize` parameter to an `int` value. The `PageSize` determines how many table rows are populated and rendered at any given time.
+
+Set the `PageSize` value, so that the rendered table rows do fit in the [TreeList height](#height). At least one table row must be completely invisible. Otherwise, empty row skeletons may display in the TreeList while users are not scrolling. The exact `PageSize` value allows you to balance between better user experience and rendering efficiency:
+
+* A larger `PageSize` value will make the TreeList display empty row skeletons more rarely while users are scrolling down. At the same time, the TreeList may be re-rendering the same data items repetitively if the user scrolls just a little.
+* A smaller `PageSize` will make the TreeList render a smaller number of items on each user scroll. At the same time, users will see row skeletons sooner or more frequently during scrolling.
+
+## RowHeight
+
+Set the `RowHeight` parameter to a `decimal` value. The TreeList uses it to set an inline `height` style in pixels to all TreeList table rows (``).
+
+The `RowHeight` value must be large enough to accommodate the cell content in all rows, even if the content differs. In other words, the `RowHeight` setting must apply the same or greater table row height than what the browser would normally render. The effective row height depends on:
+
+* The cell content and text wrapping
+* The CSS theme, including font size, line height, and cell paddings.
+
+For example, the following list shows the minimum valid `RowHeight` values when using the [built-in CSS themes](slug:themes-overview), single-line plain text content, and no command buttons:
+
+* `36` for the Default theme (`14px` font size, `20px` line height, and 2 * `8px` vertical paddings)
+* `40` for the Bootstrap theme (`16px` font size, `24px` line height, and 2 * `8px` vertical paddings)
+* `48` for the Material theme (`14px` font size, `28px` line height, and 2 * `10px` vertical paddings)
+* `44` for the Fluent theme (`14px` font size, `20px` font size and 2 * `12px` vertical paddings)
+
+> Browsers treat table row `height` styles as `min-height` styles. If the table row content cannot fit in the set `RowHeight`, the browser expands the table row. The TreeList configuration must not allow this to happen. It is crucial that all TreeList table rows display with the same effective height when using virtial scrolling, otherwise the virtual scrolling experience will break.
+
+The `RowHeight` parameter value cannot change at runtime, unless the application recreates the whole TreeList component by removing it from the web page temporarily.
+
+If necessary, you can also use the `RowHeight` parameter without virtual row scrolling.
+
+## Limitations
+
+There is a [browser limitation, which affects the maximum number of data items in a virtual TreeList](slug:grid-kb-virtualization-many-records). The problem occurs with millions of items and you can partially mitigate it by [changing the TreeList styles to make the row height smaller](slug:grid-kb-reduce-row-height).
+
+In addition to virtual scrolling, another approach to optimize the rendering performance is to use [TreeList paging](slug:treelist-paging).
+
+## Example
+
+>caption Virtual TreeList scrolling
````RAZOR
+ FilterMode="TreeListFilterMode.FilterMenu"
+ Height="360px"
+ PageSize="20"
+ RowHeight="40"
+ ScrollMode="@TreeListScrollMode.Virtual"
+ Sortable="true">
-
-
-
+
+
+
+
@code {
- private List TreeListData { get; set; } = new();
+ private List? TreeListData { get; set; }
- protected override void OnInitialized()
- {
- for (int i = 1; i <= 1000; i++)
- {
- TreeListData.Add(new Employee()
- {
- Id = i,
- ParentId = i <= 3 ? null : i % 3 + 1,
- FirstName = "First " + i,
- LastName = "Last " + i,
- Position = i <= 3 ? "Team Lead" : "Software Engineer"
- });
- }
+ private EmployeeService TreeListEmployeeService { get; set; } = new(treeLevelCount: 3, rootItemCount: 10, childItemCount: 20);
- base.OnInitialized();
+ protected override async Task OnInitializedAsync()
+ {
+ TreeListData = await TreeListEmployeeService.Read();
}
public class Employee
{
public int Id { get; set; }
public int? ParentId { get; set; }
- public string FirstName { get; set; }
- public string LastName { get; set; }
- public string Position { get; set; }
+ public bool HasChildren { get; set; }
+ public string Name { get; set; } = string.Empty;
+ public decimal? Salary { get; set; }
+ public DateTime? HireDate { get; set; }
+ public bool IsDriver { get; set; }
}
-}
-````
-
-## Notes
-There are several things to keep in mind when using virtual scrolling:
+ #region Data Service
-* The `RowHeight` is a decimal value that is always interpreted as pixels. The TreeList `Height` does not have to be in pixels, but it may help you calculate the `PageSize` (see below).
+ public class EmployeeService
+ {
+ private List Items { get; set; } = new();
- * If the row/cell height the browser renders is larger than the `RowHeight` value, the browser will ignore it. It can depend on the chosen Theme, other CSS rules, or cell data that occupies more than one row. Inspect the rendered HTML to make sure the grid setting matches the rendering.
+ private readonly int TreeLevelCount;
+ private readonly int RootItemCount;
+ private readonly int ChildItemCount;
- The default TreeList rendering has padding in the cells, and the loading sign has a line height set in order to render. This may impose some minimum heights that can vary with the theme and/or custom styles on the page.
+ private int LastId { get; set; }
+ private Random Rnd { get; set; } = Random.Shared;
- * The `RowHeight` must not change at runtime, because the new dimensions will cause issues with the scrolling logic.
+ public async Task> Read()
+ {
+ await SimulateAsyncOperation();
+ return Items;
+ }
- * Browser zoom or monitor DPI settings can cause the browser to render different dimensions than the expected and/or non-integer values, which can break the virtualization logic.
+ private async Task SimulateAsyncOperation()
+ {
+ await Task.Delay(100);
+ }
-* Do not mix virtualization with paging, as they are alternatives to the same feature.
+ private void PopulateChildren(List items, int? parentId, int level)
+ {
+ int itemCount = level == 1 ? RootItemCount : ChildItemCount;
+ for (int i = 1; i <= itemCount; i++)
+ {
+ int itemId = ++LastId;
+ items.Add(new Employee()
+ {
+ Id = itemId,
+ ParentId = parentId,
+ HasChildren = level < TreeLevelCount,
+ Name = $"Employee Name {itemId}", // {level}-{i}
+ Salary = Rnd.Next(1_000, 10_000) * 1.23m,
+ HireDate = DateTime.Today.AddDays(-Rnd.Next(365, 3650)),
+ IsDriver = itemId % 2 == 0
+ });
+ if (level < TreeLevelCount)
+ {
+ PopulateChildren(items, itemId, level + 1);
+ }
+ }
+ }
-* Provide for a `PageSize` of the TreeList that is large enough, so that the loaded table rows do not fit in the scrollable data area, otherwise the vertical virtual scrollbar will not be created and scrolling will not work. To do this, take into account the `Height` of the TreeList and the `RowHeight`.
+ public EmployeeService(int treeLevelCount = 3, int rootItemCount = 3, int childItemCount = 2)
+ {
+ TreeLevelCount = treeLevelCount;
+ RootItemCount = rootItemCount;
+ ChildItemCount = childItemCount;
+ List items = new();
+ PopulateChildren(items, null, 1);
+ Items = items;
+ }
+ }
- * The `PageSize` controls how many rows are rendered at any given time, and how many items are requested from the data source when loading data on demand. You should avoid setting large page sizes, you need to only fill up the TreeList data viewport.
+ #endregion Data Service
+}
+````
## See Also
- * [Live Demo: TreeList Virtual Scrolling](https://demos.telerik.com/blazor-ui/treelist/virtual-scrolling)
-
+* [Live Demo: TreeList Virtual Scrolling](https://demos.telerik.com/blazor-ui/treelist/virtual-scrolling)
+* [How to Disable Row Placeholders During Virtual Scrolling](slug:grid-kb-hide-virtual-row-skeletons)
diff --git a/knowledge-base/grid-hide-virtual-row-skeletons.md b/knowledge-base/grid-hide-virtual-row-skeletons.md
new file mode 100644
index 0000000000..1acccf04a2
--- /dev/null
+++ b/knowledge-base/grid-hide-virtual-row-skeletons.md
@@ -0,0 +1,88 @@
+---
+title: Hide Grid Virtual Row Skeletons
+description: Learn how to hide / remove / disable the Grid and TreeList cell placeholder skeletons during virtual row scrolling.
+type: how-to
+page_title: How To Hide Row Skeletons During Virtual Grid Scrolling
+slug: grid-kb-hide-virtual-row-skeletons
+tags: blazor, grid, treelist, skeleton, styles, css
+ticketid: 1658135, 1642794
+res_type: kb
+---
+
+## Environment
+
+
+
+
+ Product |
+ Grid for Blazor, TreeList for Blazor |
+
+
+
+
+## Description
+
+This KB article answers the following questions:
+
+* How to remove the Grid row placeholders during virtual scrolling?
+* How to hide the skeletons that appear in empty table cells during virtual scrolling?
+* How to disable the Grid cell placeholders?
+* How to turn off the Grid loader indicators inside the virtual rows?
+
+## Solution
+
+Apply a `display:none` or `visibility:hidden` CSS style to the `.k-skeleton` selector inside Grid table cells.
+
+>caption Removing placeholder skeletons during virtual Grid scrolling
+
+````RAZOR
+
+
+
+
+
+
+
+
+
+
+@code {
+ private List GridData { get; set; } = new();
+
+ protected override void OnInitialized()
+ {
+ for (int i = 1; i <= 1000; i++)
+ {
+ GridData.Add(new Product()
+ {
+ Id = i,
+ Name = $"Name {i}",
+ Price = Random.Shared.Next(1, 100) * 1.23m,
+ Quantity = Random.Shared.Next(0, 1000)
+ });
+ }
+ }
+
+ public class Product
+ {
+ public int Id { get; set; }
+ public string Name { get; set; } = string.Empty;
+ public decimal Price { get; set; }
+ public int Quantity { get; set; }
+ }
+}
+````
+
+## See Also
+
+* [Virtual Grid Scrolling](slug:components/grid/virtual-scrolling)
+* [Virtual TreeList Scrolling](slug:treelist-virtual-scrolling)
diff --git a/knowledge-base/grid-reduce-row-height.md b/knowledge-base/grid-reduce-row-height.md
new file mode 100644
index 0000000000..03faeed46d
--- /dev/null
+++ b/knowledge-base/grid-reduce-row-height.md
@@ -0,0 +1,115 @@
+---
+title: Reduce Grid Row Height and Cell Paddings
+description: Learn how to decrease the Grid and TreeList row height and remove table cell paddings to make the rows smaller.
+type: how-to
+page_title: How To Reduce the Grid Row Height and Remove Cell Paddings
+slug: grid-kb-reduce-row-height
+tags: blazor, grid, treelist, styles, css
+ticketid:
+res_type: kb
+---
+
+## Environment
+
+
+
+
+ Product |
+ Grid for Blazor, TreeList for Blazor |
+
+
+
+
+## Description
+
+This KB article answers the following questions:
+
+* How to reduce the Grid row height?
+* How to decrease the Grid cell paddings and height?
+
+## Solution
+
+There are two ways to reduce the row height:
+
+* Use the [`Size` parameter](slug:grid-sizing). This will apply predefined amount of padding (empty space) around the cell content.
+* Use [custom CSS to override the Telerik theme](slug:themes-override). This allows full control over the component styling.
+
+The TreeList uses the same HTML output and CSS classes as the Grid. The suggested CSS code below is applicable to both components.
+
+>caption Changing the Grid row height
+
+````RAZOR
+Change Grid Row Height
+
+Use Default Styles
+
+
+
+
+
+
+
+
+
+Use Grid Size
Parameter
+
+
+
+
+
+
+
+
+
+Use Custom CSS
+
+
+
+
+
+
+
+
+
+
+
+@code {
+ private List GridData { get; set; } = new();
+
+ protected override void OnInitialized()
+ {
+ for (int i = 1; i <= 3; i++)
+ {
+ GridData.Add(new Product()
+ {
+ Id = i,
+ Name = $"Name {i}",
+ Price = Random.Shared.Next(1, 100) * 1.23m,
+ Quantity = Random.Shared.Next(0, 1000)
+ });
+ }
+ }
+
+ public class Product
+ {
+ public int Id { get; set; }
+ public string Name { get; set; } = string.Empty;
+ public decimal Price { get; set; }
+ public int Quantity { get; set; }
+ }
+}
+````
+
+## See Also
+
+* [How to Change the Grid Font Size](slug:grid-kb-change-font-size)
+* [How to Change the Grid Size](slug:grid-sizing)
+* [How to Override Telerik Theme CSS Styles](slug:themes-override)
diff --git a/knowledge-base/grid-virtual-scrolling-not-working.md b/knowledge-base/grid-virtual-scrolling-not-working.md
index 4f72808c6e..6a45a1cc81 100644
--- a/knowledge-base/grid-virtual-scrolling-not-working.md
+++ b/knowledge-base/grid-virtual-scrolling-not-working.md
@@ -93,6 +93,12 @@ There are several common causes for that behavior:
## Solution
+
Set the `RowHeight` parameter to a fixed value in pixels so that it accommodates the content (depending on the content, padding, margins, font-size and other rules and settings on your app such the Theme and CSS related rules) and matches the monitor and browser settings.
-You can read more in the [Notes section of the Virtual Scrolling article](slug:components/grid/virtual-scrolling).
+You can read more in the [`RowHeight` section of the Grid Virtual Scrolling article](slug:components/grid/virtual-scrolling#rowheight).
+
+## See Also
+
+* [Virtual Grid Scrolling](slug:components/grid/virtual-scrolling)
+* [Virtual TreeList Scrolling](slug:treelist-virtual-scrolling)
diff --git a/knowledge-base/grid-virtualization-many-records.md b/knowledge-base/grid-virtualization-many-records.md
index 030df02d70..2d3f87879d 100644
--- a/knowledge-base/grid-virtualization-many-records.md
+++ b/knowledge-base/grid-virtualization-many-records.md
@@ -1,41 +1,36 @@
---
-title: Virtual Scroll does not show all items
+title: Virtual Grid Scroll Does Not Show All Table Rows
description: When you have many items in the grid, you may be unable to see all of them with virtual scrolling
type: troubleshooting
-page_title: Virtual Scrolling Does Not Show All Items
+page_title: Virtual Grid Scroll Does Not Show All Data Items
slug: grid-kb-virtualization-many-records
-position:
-tags:
+position:
+tags:
ticketid: 1502885
res_type: kb
---
## Environment
+
-
-
- Product |
- Grid for Blazor |
-
-
+
+
+ Product |
+ Grid for Blazor, TreeList for Blazor |
+
+
-
## Description
-The virtual grid breaks when there are more than 3.000.000 records in TotalCount.
-I cannot see all records in the grid with virtual scrolling when there are many records.
+This KB article discusses the following issues:
-I cannot scroll to the end of the records when I have many records.
+* The virtual grid breaks when there are more than 3.000.000 records in TotalCount.
+* I cannot see all records in the grid with virtual scrolling when there are many records.
+* I cannot scroll to the end of the records when I have many records.
Other symptoms can include the grid content overflowing its parent and hiding content after the grid, or you could see a border from the grid near the end of the scrollable container.
-In this article:
-
-* [Steps to Reproduce](#steps-to-reproduce)
-* [Possible Cause](#possible-cause)
-* [Solution](#solution)
-
## Steps to Reproduce
>caption Sample reproducible - try dragging the scrollbar to the end - you won't see record number 1 000 000
@@ -86,17 +81,18 @@ Total items: @GridData.Count
The issue with the content overflow is the same - when the element size limit is reached, the browser does not render the element correctly and it overflows its parent.
->caption Overflowing content due to browser element size limit (see additional code below)\
+>caption Overflowing content due to browser element size limit (see additional code below)

>caption Add this code just after the grid closing tag to color the element borders like in the image above to see the issue
-````RAZOR
+
+````RAZOR.skip-repl
-something after the grid that I can't see because of the grid issue
+Something below the Grid that I can't see.
````
-
## Possible Cause
+
Browsers have a limitation on how large (tall or wide) an element can be. This limits how much data you can fit and how far the user can scroll.
The height of the actual grid data element is `total records count` x `row height`. For example, with 60px row height, 1 million records will be 60 000 000 pixels.
-Browsers can usually go up to about 33 000 000 pixels.
+Browsers can usually go up to about 33,000,000 pixels.
Thus, the scrollbar can only get so small, and you can only scroll to a certain extent of the data.
@@ -123,7 +119,12 @@ Thus, the scrollbar can only get so small, and you can only scroll to a certain

+## Solution
+A possible way to mitigate the problem is to [reduce the Grid row height](slug:grid-kb-reduce-row-height).
+If this is not enough, the only possible solution is to use [paging](slug:components/grid/features/paging).
-## Solution
-The only possible solution if you have so many records is to use the standard [paging](slug:components/grid/features/paging).
+## See Also
+
+* [Virtual Grid Scrolling](slug:components/grid/virtual-scrolling)
+* [Virtual TreeList Scrolling](slug:treelist-virtual-scrolling)
From 9ec5f030dc200a61464c6a381571bad050d4ad26 Mon Sep 17 00:00:00 2001
From: Dimo Dimov <961014+dimodi@users.noreply.github.com>
Date: Tue, 11 Mar 2025 15:02:08 +0200
Subject: [PATCH 2/7] Update components/treelist/virtual-scrolling.md
Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com>
---
components/treelist/virtual-scrolling.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/components/treelist/virtual-scrolling.md b/components/treelist/virtual-scrolling.md
index 056ac86c40..69b54177b6 100644
--- a/components/treelist/virtual-scrolling.md
+++ b/components/treelist/virtual-scrolling.md
@@ -10,7 +10,7 @@ position: 25
# TreeList Virtual Scrolling
-Virtual TreeList scrolling allows users to scroll vertically through all records in the TreeList data source. The feature is an alternative to paging.
+The TreeList virtual scrolling feature allows users to scroll vertically through all records in the data source. The feature is an alternative to paging.
To enhance the rendering performance, the TreeList reuses the same set of HTML elements. Loading indicators (skeletons) appear in the table cells during scrolling and data loading. If the user scrolls back up after scrolling down to the next set of rows, the previous data reloads from the data source, similar to regular paging, with the scroll distance determining the data to be loaded.
From 19f179a8f45ecb4936263965ca9196b6895be09d Mon Sep 17 00:00:00 2001
From: Dimo Dimov <961014+dimodi@users.noreply.github.com>
Date: Tue, 11 Mar 2025 15:02:25 +0200
Subject: [PATCH 3/7] Update knowledge-base/grid-virtualization-many-records.md
Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com>
---
knowledge-base/grid-virtualization-many-records.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/knowledge-base/grid-virtualization-many-records.md b/knowledge-base/grid-virtualization-many-records.md
index 2d3f87879d..d7c9645fe9 100644
--- a/knowledge-base/grid-virtualization-many-records.md
+++ b/knowledge-base/grid-virtualization-many-records.md
@@ -126,5 +126,5 @@ If this is not enough, the only possible solution is to use [paging](slug:compon
## See Also
-* [Virtual Grid Scrolling](slug:components/grid/virtual-scrolling)
+* [Grid Virtual Scrolling](slug:components/grid/virtual-scrolling)
* [Virtual TreeList Scrolling](slug:treelist-virtual-scrolling)
From 5fe58892fb85014b6263b8af6aa12866e52ab27f Mon Sep 17 00:00:00 2001
From: Dimo Dimov <961014+dimodi@users.noreply.github.com>
Date: Tue, 11 Mar 2025 15:02:33 +0200
Subject: [PATCH 4/7] Update knowledge-base/grid-virtualization-many-records.md
Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com>
---
knowledge-base/grid-virtualization-many-records.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/knowledge-base/grid-virtualization-many-records.md b/knowledge-base/grid-virtualization-many-records.md
index d7c9645fe9..615fdd0433 100644
--- a/knowledge-base/grid-virtualization-many-records.md
+++ b/knowledge-base/grid-virtualization-many-records.md
@@ -127,4 +127,4 @@ If this is not enough, the only possible solution is to use [paging](slug:compon
## See Also
* [Grid Virtual Scrolling](slug:components/grid/virtual-scrolling)
-* [Virtual TreeList Scrolling](slug:treelist-virtual-scrolling)
+* [TreeList Virtual Scrolling](slug:treelist-virtual-scrolling)
From d1fb70042477bc72cd1a698d3902c4832d611f8b Mon Sep 17 00:00:00 2001
From: Dimo Dimov <961014+dimodi@users.noreply.github.com>
Date: Tue, 11 Mar 2025 15:02:45 +0200
Subject: [PATCH 5/7] Update knowledge-base/grid-virtualization-many-records.md
Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com>
---
knowledge-base/grid-virtualization-many-records.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/knowledge-base/grid-virtualization-many-records.md b/knowledge-base/grid-virtualization-many-records.md
index 615fdd0433..d67bda6d6d 100644
--- a/knowledge-base/grid-virtualization-many-records.md
+++ b/knowledge-base/grid-virtualization-many-records.md
@@ -1,5 +1,5 @@
---
-title: Virtual Grid Scroll Does Not Show All Table Rows
+title: Grid Virtual Scrolling Does Not Show All Table Rows
description: When you have many items in the grid, you may be unable to see all of them with virtual scrolling
type: troubleshooting
page_title: Virtual Grid Scroll Does Not Show All Data Items
From 567b9592b104893f9e50ca6dc7b68719481f4edb Mon Sep 17 00:00:00 2001
From: Dimo Dimov <961014+dimodi@users.noreply.github.com>
Date: Tue, 11 Mar 2025 15:03:12 +0200
Subject: [PATCH 6/7] Update knowledge-base/grid-virtualization-many-records.md
Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com>
---
knowledge-base/grid-virtualization-many-records.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/knowledge-base/grid-virtualization-many-records.md b/knowledge-base/grid-virtualization-many-records.md
index d67bda6d6d..202f78bcea 100644
--- a/knowledge-base/grid-virtualization-many-records.md
+++ b/knowledge-base/grid-virtualization-many-records.md
@@ -2,7 +2,7 @@
title: Grid Virtual Scrolling Does Not Show All Table Rows
description: When you have many items in the grid, you may be unable to see all of them with virtual scrolling
type: troubleshooting
-page_title: Virtual Grid Scroll Does Not Show All Data Items
+page_title: Grid Virtual Scrolling Does Not Show All Table Rows
slug: grid-kb-virtualization-many-records
position:
tags:
From 6965bb2221d1ae6754949f60e961e80e7c7690f7 Mon Sep 17 00:00:00 2001
From: Dimo Dimov <961014+dimodi@users.noreply.github.com>
Date: Tue, 11 Mar 2025 15:03:49 +0200
Subject: [PATCH 7/7] Update components/grid/virtual-scrolling.md
Co-authored-by: Tsvetomir Hristov <106250052+Tsvetomir-Hr@users.noreply.github.com>
---
components/grid/virtual-scrolling.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/components/grid/virtual-scrolling.md b/components/grid/virtual-scrolling.md
index 25041c6424..2bf65ea62b 100644
--- a/components/grid/virtual-scrolling.md
+++ b/components/grid/virtual-scrolling.md
@@ -10,7 +10,7 @@ position: 60
# Grid Virtual Scrolling
-Virtual Grid scrolling allows users to scroll vertically through all records in the Grid data source. The feature is an alternative to paging.
+The Grid virtual scrolling feature allows users to scroll vertically through all records in the Grid data source. The feature is an alternative to paging.
To enhance the rendering performance, the Grid reuses the same set of HTML elements. Loading indicators (skeletons) appear in the table cells during scrolling and data loading. If the user scrolls back up after scrolling down to the next set of rows, the previous data reloads from the data source, similar to regular paging, with the scroll distance determining the data to be loaded.