Skip to content

Commit 2040046

Browse files
svdimitrradkostanev
authored andcommitted
docs(grid): revamp the virtual rows article
1 parent a037adb commit 2040046

File tree

1 file changed

+243
-31
lines changed

1 file changed

+243
-31
lines changed

components/grid/virtual-scrolling.md

Lines changed: 243 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,39 @@ position: 60
1010

1111
# Virtual Scrolling
1212

13-
Virtual scrolling is an alternative to paging. Instead of using a pager, the user scrolls vertically through all records in the data source.
13+
Virtual scrolling provides an alternative to paging. Instead of utilizing a pager, the user scrolls vertically through all records in the data source.
1414

15-
The same set of elements is reused to improve the rendering performance. While the next data is loading, a loading indicator is shown on the cells. If the user scrolls back up after scrolling down to a next set of rows, the previous data will be loaded anew from the data source, like with regular paging, but the scroll distance determines the data to be loaded.
15+
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.
1616

17-
You can also Virtually Scroll the Grid Columns. More information can be found in the [Column Virtualization]({%slug grid-columns-virtual%}) article.
17+
You can also Virtually Scroll the Grid Columns. See the [Column Virtualization]({%slug grid-columns-virtual%}) article for more information.
1818

19-
## Requirements
19+
## Using Virtual Scrolling
2020

21-
To enable virtual scrolling:
21+
Setting a Value for the Height Parameter
2222

23-
1. Set `ScrollMode="@GridScrollMode.Virtual"` - this enables the virtualization of items
24-
25-
2. Provide `Height`, `RowHeight`, and `PageSize` to the grid - this lets the grid calculate the position of the user in order to fetch the correct set of items from the data source.
23+
1. Set the `ScrollMode` parameter to `GridScrollMode.Virtual` (the default value is `Scrollable`).
24+
1. [Set the Height parameter](#setting-a-value-for-the-height-parameter).
25+
1. [Set the RowHeight parameter](#setting-a-value-for-the-rowheight-parameter).
26+
1. [Set the PageSize parameter](#setting-a-value-for-the-pagesize-parameter).
2627

2728
>caption Sample of virtual scrolling in the Telerik Grid for Blazor
2829
2930
````CSHTML
31+
32+
````
33+
34+
## Setting a Value for the Height Parameter
35+
36+
Set the `Height` parameter to a `string` value. The value can be in:
37+
38+
* `Pixels` (e.g., `px`)
39+
* `Percent` (e.g., `%`) - If you set the `Height` parameter to a percent value, ensure that the wrapper of the Grid has a fixed height set in `px`.
40+
* `vh` or other relative CSS units (e.g., `vmin`, `vmax`).
41+
42+
The tabs below show how to set the `Height` parameter with the different value options.
43+
44+
<div class="skip-repl"></div>
45+
````Pixel
3046
@using Telerik.DataSource
3147
@using Telerik.DataSource.Extensions
3248
@@ -79,54 +95,250 @@ To enable virtual scrolling:
7995
}
8096
}
8197
````
98+
````Percent
99+
@using Telerik.DataSource
100+
@using Telerik.DataSource.Extensions
82101
83-
>tip Set suitable widths for columns that will render long text. This will prevent the cell content from breaking into multiple lines, which will increase the row height. See the notes below for more details.
102+
<div style="height: 600px">
103+
<TelerikGrid OnRead="@OnGridRead"
104+
TItem="@Product"
105+
ScrollMode="@GridScrollMode.Virtual"
106+
Height="100%" RowHeight="60" PageSize="20"
107+
Sortable="true" FilterMode="@GridFilterMode.FilterRow">
108+
<GridColumns>
109+
<GridColumn Field="@nameof(Product.Name)" Title="Product Name" />
110+
<GridColumn Field="@nameof(Product.Stock)" />
111+
</GridColumns>
112+
</TelerikGrid>
113+
</div>
84114
85-
## Notes
115+
@code {
116+
private List<Product> GridData { get; set; } = new List<Product>();
86117
87-
There are several things to keep in mind when using virtual scrolling:
118+
private async Task OnGridRead(GridReadEventArgs args)
119+
{
120+
await Task.Delay(200); // simulate network delay
88121
89-
* The `RowHeight` is a decimal value that is always considered as pixel values. If you use [row template]({%slug components/grid/features/templates%}#row-template), make sure it matches the `RowHeight`. The grid `Height` does not have to be in pixels, but it may help you calculate the `PageSize` (see below).
122+
DataSourceResult result = GridData.ToDataSourceResult(args.Request);
90123
91-
* If the row/cell height the browser would render is larger than the `RowHeight` value, the browser will ignore it. It can depend on the chosen Theme or other CSS rules, or on cell data that falls on more than one row. Inspect the rendered HTML to make sure the grid setting matches the rendering.
124+
args.Data = result.Data;
125+
args.Total = result.Total;
126+
args.AggregateResults = result.AggregateResults;
127+
}
128+
129+
protected override void OnInitialized()
130+
{
131+
GridData = new List<Product>();
132+
var rnd = new Random();
133+
134+
for (int i = 1; i <= 1000; i++)
135+
{
136+
GridData.Add(new Product()
137+
{
138+
Id = i,
139+
Name = $"Product {i}",
140+
Stock = rnd.Next(0, 100)
141+
});
142+
}
143+
}
144+
145+
public class Product
146+
{
147+
public int Id { get; set; }
148+
public string Name { get; set; } = string.Empty;
149+
public int Stock { get; set; }
150+
}
151+
}
152+
````
153+
````RelativeUnits
154+
@using Telerik.DataSource
155+
@using Telerik.DataSource.Extensions
92156
93-
The default grid 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. You can remove both with the following rules: `.k-placeholder-line{display:none;} .k-grid td{margin:0;padding:0;}`.
157+
<div>Select a relative CSS unit from the RadioGroup to see how the Grid's Height reacts to different relative CSS units.</div>
94158
95-
* The `RowHeight` must not change at runtime, because the new dimensions will cause issues with the scrolling logic.
159+
<TelerikRadioGroup Data="@RelativeUnitsOptions"
160+
Value="@ChosenRelativeUnit"
161+
ValueChanged="@((int relativeUnitId) => RadioGroupChanged(relativeUnitId))"
162+
ValueField="@nameof(RelativeUnitsDescriptor.RelativeUnitId)"
163+
TextField="@nameof(RelativeUnitsDescriptor.RelativeUnitText)">
164+
</TelerikRadioGroup>
96165
97-
* 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.
166+
<TelerikGrid OnRead="@OnGridRead"
167+
TItem="@Product"
168+
ScrollMode="@GridScrollMode.Virtual"
169+
Height="480px" RowHeight="60" PageSize="20"
170+
Sortable="true" FilterMode="@GridFilterMode.FilterRow">
171+
<GridColumns>
172+
<GridColumn Field="@nameof(Product.Name)" Title="Product Name" />
173+
<GridColumn Field="@nameof(Product.Stock)" />
174+
</GridColumns>
175+
</TelerikGrid>
98176
99-
* Do not mix virtualization with paging, as they are alternatives to the same feature.
177+
@code {
178+
private int ChosenRelativeUnit { get; set; }
100179
101-
* Provide for a `PageSize` of the Grid 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 grid and the `RowHeight`.
180+
private string GridHeight { get; set; }
102181
103-
* 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 (see below). You should avoid setting large page sizes, you need to only fill up the grid data viewport.
182+
private void RadioGroupChanged(int relativeUnitId)
183+
{
184+
ChosenRelativeUnit = relativeUnitId;
104185
105-
* To load data on demand, use the [`OnRead` event]({%slug components/grid/manual-operations%}), and in it, use the `PageSize` and `Skip` parameters to know what data to return, instead of `PageSize` and `Page` as with regular paging.
186+
RelativeUnitsDescriptor relativeUnit = RelativeUnitsOptions.FirstOrDefault(x => x.RelativeUnitId == relativeUnitId);
106187
107-
* Data requests will be made when the user scrolls, but not necessarily when they scroll an entire page of data. Row virtualization is a user experience and UI optimization technique and not necessarily a data request optimization. The user may scroll a few rows, or they may keep scrolling and skip many pages. The grid cannot predict the user action, so it needs to request the data when the user changes what should be displayed.
188+
GridHeight = "50" + relativeUnit.RelativeUnitText;
189+
}
108190
109-
* Horizontal scrolling is not virtualized by default and all columns are rendered. You can enable [Column Virtualization]({%slug grid-columns-virtual%}) separately too.
191+
private async Task OnGridRead(GridReadEventArgs args)
192+
{
193+
await Task.Delay(200); // simulate network delay
110194
111-
* Multiple Selection has some specifics when you use the `OnRead` event, you can read more about its behavior in the [Multiple Selection]({%slug components/grid/selection/multiple%}#checkbox-selection) article.
195+
DataSourceResult result = GridData.ToDataSourceResult(args.Request);
112196
113-
## Limitations
197+
args.Data = result.Data;
198+
args.Total = result.Total;
199+
args.AggregateResults = result.AggregateResults;
200+
}
114201
115-
Virtualization is mainly a technique for improving client-side (rendering) performance and the user experience. Its cost is that some features of the grid do not work with it. An alternative to that is to use [regular paging]({%slug components/grid/features/paging%}) with [manual data source operations]({%slug components/grid/manual-operations%}) to implement the desired performance of the data retrieval.
202+
protected override void OnInitialized()
203+
{
204+
GridHeight = "50" + RelativeUnitsOptions.FirstOrDefault().RelativeUnitText;
116205
117-
List of the known limitations of the virtual scrolling feature:
206+
GridData = new List<Product>();
118207
119-
* [Hierarchy]({%slug components/grid/features/hierarchy%}) is not supported.
208+
var rnd = new Random();
120209
121-
* [Grouping]({%slug components/grid/features/grouping%}) is not supported. [Loading Group Data On Demand]({%slug grid-group-lod%}) is supported, however.
210+
for (int i = 1; i <= 1000; i++)
211+
{
212+
GridData.Add(new Product()
213+
{
214+
Id = i,
215+
Name = $"Product {i}",
216+
Stock = rnd.Next(0, 100)
217+
});
218+
}
219+
}
122220
123-
* The `Data` of the grid must contain more items than the `PageSize` in order for the virtual scrolling feature to work. You can work around this with something similar to `ScrollMode="@(DataCollection.Count() > 30 ? GridScrollMode.Virtual : GridScrollMode.Scrollable)"`
221+
private List<Product> GridData { get; set; } = new List<Product>();
124222
125-
* If you set the `Skip` manually through the grid [state]({%slug grid-state%}), you must ensure the value is valid and does not result in items that cannot fill up the viewport. You can find more details in the [Setting Too Large Skip]({%slug grid-kb-large-skip-virtualization%}) Knowledge Base article.
223+
private List<RelativeUnitsDescriptor> RelativeUnitsOptions { get; set; } = new List<RelativeUnitsDescriptor>
224+
{
225+
new RelativeUnitsDescriptor { RelativeUnitId = 1, RelativeUnitText = "vm" },
226+
new RelativeUnitsDescriptor { RelativeUnitId = 2, RelativeUnitText = "vmax" },
227+
new RelativeUnitsDescriptor { RelativeUnitId = 3, RelativeUnitText = "vmin" }
228+
};
126229
127-
* When there are too many records, the browser may not let you scroll down to all of them, read more in the [Virtual Scroll does not show all items]({%slug grid-kb-virtualization-many-records%}) KB article.
230+
public class Product
231+
{
232+
public int Id { get; set; }
233+
public string Name { get; set; } = string.Empty;
234+
public int Stock { get; set; }
235+
}
236+
237+
public class RelativeUnitsDescriptor
238+
{
239+
public int RelativeUnitId { get; set; }
240+
public string RelativeUnitText { get; set; }
241+
}
242+
}
243+
````
244+
245+
## Setting a Value for the RowHeight Parameter
246+
247+
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.
248+
249+
>tip The Grid renders padding in the cells by default. The loading skeletons has 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.
250+
251+
>tip Ensure the height of the td element matches the `RowHeight` when using the [Row Template]({%slug grid-templates-row%}).
252+
253+
>tip Do not change the value of the RowHeight parameter at runtime.
254+
255+
````CSHTML
256+
@* Remove the default padding and margin from the cells and remove the default line height of the loading skeletons to reduce the row height. *@
257+
258+
@using Telerik.DataSource
259+
@using Telerik.DataSource.Extensions
260+
261+
<style>
262+
.small-row-height .k-placeholder-line {
263+
display: none;
264+
}
265+
266+
.small-row-height.k-grid td {
267+
margin: 0;
268+
padding: 0;
269+
}
270+
</style>
271+
272+
<TelerikGrid OnRead="@OnGridRead"
273+
TItem="@Product"
274+
ScrollMode="@GridScrollMode.Virtual"
275+
Height="480px" RowHeight="30" PageSize="20"
276+
Sortable="true" FilterMode="@GridFilterMode.FilterRow"
277+
Class="small-row-height">
278+
<GridColumns>
279+
<GridColumn Field="@nameof(Product.Name)" Title="Product Name" />
280+
<GridColumn Field="@nameof(Product.Stock)" />
281+
</GridColumns>
282+
</TelerikGrid>
283+
284+
@code {
285+
private List<Product> GridData { get; set; } = new List<Product>();
286+
287+
private async Task OnGridRead(GridReadEventArgs args)
288+
{
289+
await Task.Delay(200); // simulate network delay
290+
291+
DataSourceResult result = GridData.ToDataSourceResult(args.Request);
292+
293+
args.Data = result.Data;
294+
args.Total = result.Total;
295+
args.AggregateResults = result.AggregateResults;
296+
}
297+
298+
protected override void OnInitialized()
299+
{
300+
GridData = new List<Product>();
301+
var rnd = new Random();
302+
303+
for (int i = 1; i <= 1000; i++)
304+
{
305+
GridData.Add(new Product()
306+
{
307+
Id = i,
308+
Name = $"Product {i}",
309+
Stock = rnd.Next(0, 100)
310+
});
311+
}
312+
}
313+
314+
public class Product
315+
{
316+
public int Id { get; set; }
317+
public string Name { get; set; } = string.Empty;
318+
public int Stock { get; set; }
319+
}
320+
}
321+
````
322+
323+
## Setting a Value for the PageSize Parameter
324+
325+
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.
326+
327+
## Considerations
328+
329+
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 not compatible 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.
330+
331+
List of the known limitations of the virtual scrolling feature:
332+
333+
* [Hierarchy]({%slug components/grid/features/hierarchy%}) is not supported.
334+
335+
* [Grouping]({%slug components/grid/features/grouping%}) is not supported. [Loading Group Data On Demand]({%slug grid-group-lod%}) is supported, however.
128336

129337

130338
## See Also
131339

132340
* [Live Demo: Grid Virtual Scrolling](https://demos.telerik.com/blazor-ui/grid/virtual-scrolling)
341+
* [Documentation: Selection in Grid with virtualized rows]({%slug components/grid/selection/overview%}#selection-in-grid-with-virtualized-rows)
342+
* [Knowledge-Based Article: Virtual Scroll does not show all items]({%slug grid-kb-virtualization-many-records%})
343+
* [Knowledge-Based Article: Virtual Scrolling Does Not Work]({%slug grid-kb-virtual-scrolling-troubleshooting%})
344+
* [Knowledge-Based Article: Setting Too Large Skip]({%slug grid-kb-large-skip-virtualization%})

0 commit comments

Comments
 (0)