Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/dotnet/aspnetcore.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSteve Sanderson <SteveSandersonMS@users.noreply.github.com>2020-06-25 11:32:09 +0300
committerSteve Sanderson <SteveSandersonMS@users.noreply.github.com>2020-06-29 14:21:03 +0300
commit7b57f3d12f93e0152a80101147cbd91548d45af4 (patch)
treeafe957d51e2bf49d07ebe4e830e410127278da26 /src/Components
parentf6a6e4bd07bd4bf51c6965382156ebce22540fb7 (diff)
Blazor grid performance scenarios (#23301)
* Add complex table benchmark * Add FastGrid scenario too * Make the two grids consistent with each other * Add scenario for PlainTable * Empty commit to trigger re-rerun on CI. Clicking retry doesn't seem to be working.
Diffstat (limited to 'src/Components')
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Pages/GridRendering.razor122
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/Cell.razor59
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/Row.razor39
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/RowCollection.razor19
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/TableComponent.razor46
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/FastGrid/Grid.razor48
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/FastGrid/GridColumn.razor23
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/MainLayout.razor3
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/Cell.razor30
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/Row.razor35
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/RowCollection.razor19
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/TableComponent.razor44
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/wwwroot/benchmarks/grid.js105
-rw-r--r--src/Components/benchmarkapps/Wasm.Performance/TestApp/wwwroot/benchmarks/index.js1
14 files changed, 592 insertions, 1 deletions
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Pages/GridRendering.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Pages/GridRendering.razor
new file mode 100644
index 0000000000..4fa366f44c
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Pages/GridRendering.razor
@@ -0,0 +1,122 @@
+@page "/gridrendering"
+@inject IJSRuntime JSRuntime
+@using Wasm.Performance.TestApp.Shared.FastGrid
+
+<h1>20 x 200 Grid</h1>
+
+<fieldset>
+ <select id="render-mode" @bind="selectedRenderMode">
+ <option>@RenderMode.FastGrid</option>
+ <option>@RenderMode.PlainTable</option>
+ <option>@RenderMode.ComplexTable</option>
+ </select>
+
+ <button id="show" @onclick="Show">Show</button>
+ <button id="hide" @onclick="Hide">Hide</button>
+ @if (forecasts != null)
+ {
+ <button id="change-page" @onclick="ChangePage">Switch pages</button>
+ }
+</fieldset>
+
+@if (forecasts == null)
+{
+ <p><em>(No data assigned)</em></p>
+}
+else if (selectedRenderMode == RenderMode.FastGrid)
+{
+ <p>FastGrid represents a minimal, optimized implementation of a grid.</p>
+
+ <Grid Data="@forecasts">
+ <GridColumn TRowData="WeatherForecast" Title="Date">@context.Date.ToShortDateString()</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="TemperatureC">@context.TemperatureC</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="TemperatureF">@context.TemperatureF</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="Summary">@context.Summary</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="Date">@context.Date.ToShortDateString()</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="TemperatureC">@context.TemperatureC</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="TemperatureF">@context.TemperatureF</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="Summary">@context.Summary</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="Date">@context.Date.ToShortDateString()</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="TemperatureC">@context.TemperatureC</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="TemperatureF">@context.TemperatureF</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="Summary">@context.Summary</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="Date">@context.Date.ToShortDateString()</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="TemperatureC">@context.TemperatureC</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="TemperatureF">@context.TemperatureF</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="Summary">@context.Summary</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="Date">@context.Date.ToShortDateString()</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="TemperatureC">@context.TemperatureC</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="TemperatureF">@context.TemperatureF</GridColumn>
+ <GridColumn TRowData="WeatherForecast" Title="Summary">@context.Summary</GridColumn>
+ </Grid>
+}
+else if (selectedRenderMode == RenderMode.PlainTable)
+{
+ <p>PlainTable represents a minimal but not optimized implementation of a grid.</p>
+
+ <Wasm.Performance.TestApp.Shared.PlainTable.TableComponent Data="@forecasts" Columns="@Columns" />
+}
+else if (selectedRenderMode == RenderMode.ComplexTable)
+{
+ <p>ComplexTable represents a maximal, not optimized implementation of a grid, using a wide range of Blazor features at once.</p>
+
+ <Wasm.Performance.TestApp.Shared.ComplexTable.TableComponent Data="@forecasts" Columns="@Columns" />
+}
+
+@code {
+ enum RenderMode { PlainTable, ComplexTable, FastGrid }
+
+ private RenderMode selectedRenderMode = RenderMode.FastGrid;
+
+ private WeatherForecast[] forecasts;
+ public List<string> Columns { get; set; } = new List<string>
+{
+ "Date", "TemperatureC", "TemperatureF", "Summary",
+ "Date", "TemperatureC", "TemperatureF", "Summary",
+ "Date", "TemperatureC", "TemperatureF", "Summary",
+ "Date", "TemperatureC", "TemperatureF", "Summary",
+ "Date", "TemperatureC", "TemperatureF", "Summary",
+ };
+
+ private static string[] sampleSummaries = new[] { "Balmy", "Chilly", "Freezing", "Bracing" };
+ private static WeatherForecast[] staticSampleDataPage1 = Enumerable.Range(0, 200).Select(CreateSampleDataItem).ToArray();
+ private static WeatherForecast[] staticSampleDataPage2 = Enumerable.Range(200, 200).Select(CreateSampleDataItem).ToArray();
+
+ private static WeatherForecast CreateSampleDataItem(int index) => new WeatherForecast
+ {
+ Date = DateTime.Now.Date.AddDays(index),
+ Summary = sampleSummaries[index % sampleSummaries.Length],
+ TemperatureC = index,
+ };
+
+ void Show()
+ {
+ forecasts = staticSampleDataPage1;
+ }
+
+ void Hide()
+ {
+ forecasts = null;
+ }
+
+ void ChangePage()
+ {
+ forecasts = (forecasts == staticSampleDataPage1) ? staticSampleDataPage2 : staticSampleDataPage1;
+ }
+
+ protected override void OnAfterRender(bool firstRender)
+ {
+ BenchmarkEvent.Send(JSRuntime, "Finished rendering table");
+ }
+
+ public class WeatherForecast
+ {
+ public DateTime Date { get; set; }
+
+ public int TemperatureC { get; set; }
+
+ public string Summary { get; set; }
+
+ public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
+ }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/Cell.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/Cell.razor
new file mode 100644
index 0000000000..e384a03da3
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/Cell.razor
@@ -0,0 +1,59 @@
+@using WeatherForecast = Pages.GridRendering.WeatherForecast
+
+<td @attributes="@Attributes"
+ @onclick="@(() => OnClick.Invoke(CellIndex))"
+ >
+ @switch (Field)
+ {
+ case "Date":
+ @Item.Date.ToShortDateString()
+ break;
+ case "TemperatureC":
+ @Item.TemperatureC
+ break;
+ case "TemperatureF":
+ @Item.TemperatureF
+ break;
+ case "Summary":
+ @Item.Summary
+ break;
+ }
+</td>
+
+@code {
+ [Parameter]
+ public WeatherForecast Item { get; set; }
+
+ [CascadingParameter]
+ public TableComponent ParentTable { get; set; }
+
+ [Parameter]
+ public string Field { get; set; }
+
+ [Parameter]
+ public int CellIndex { get; set; }
+
+ [Parameter]
+ public int RowIndex { get; set; }
+
+ [Parameter]
+ public bool Selected { get; set; }
+
+ [Parameter]
+ public string FormatString { get; set; }
+
+ [Parameter]
+ public Func<int, Task> OnClick { get; set; }
+
+ private protected Dictionary<string, object> Attributes
+ {
+ get
+ {
+ var attributes = new Dictionary<string, object>();
+
+ attributes["tabindex"] = CellIndex;
+
+ return attributes;
+ }
+ }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/Row.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/Row.razor
new file mode 100644
index 0000000000..00716a4c8c
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/Row.razor
@@ -0,0 +1,39 @@
+@using WeatherForecast = Pages.GridRendering.WeatherForecast
+
+<tr class="complex-table-row" style="@rowStyle">
+ @foreach (var item in Columns)
+ {
+ <Cell Item="@Item"
+ Field="@item"
+ CellIndex="1"
+ RowIndex="2"
+ Selected="@isSelected"
+ FormatString="foo"
+ OnClick="@OnCellClick">
+ </Cell>
+ }
+</tr>
+
+
+@code {
+
+ private bool isSelected = false;
+
+ private string rowStyle => isSelected ? "background-color: lightblue;" : "";
+
+ [Parameter]
+ public WeatherForecast Item { get; set; }
+
+ [Parameter]
+ public List<string> Columns { get; set; }
+
+ [Parameter]
+ public Func<int, Task> OnClick { get; set; }
+
+ Task OnCellClick(int args)
+ {
+ isSelected = !isSelected;
+
+ return OnClick.Invoke(args);
+ }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/RowCollection.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/RowCollection.razor
new file mode 100644
index 0000000000..180043c5c8
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/RowCollection.razor
@@ -0,0 +1,19 @@
+@using WeatherForecast = Pages.GridRendering.WeatherForecast
+
+@foreach (var item in Data)
+{
+ <Row Item="@item" Columns="@Columns"
+ OnClick="@OnClick"></Row>
+}
+
+
+@code {
+ [Parameter]
+ public WeatherForecast[] Data { get; set; }
+
+ [Parameter]
+ public List<string> Columns { get; set; }
+
+ [Parameter]
+ public Func<int, Task> OnClick { get; set; }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/TableComponent.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/TableComponent.razor
new file mode 100644
index 0000000000..70c95ec905
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/ComplexTable/TableComponent.razor
@@ -0,0 +1,46 @@
+@using WeatherForecast = Pages.GridRendering.WeatherForecast
+
+<table class="table">
+ <thead>
+ <tr>
+ @foreach (var item in Columns)
+ {
+ <th>@item</th>
+ }
+ </tr>
+ </thead>
+ <tbody>
+ <CascadingValue Value="@this">
+ <RowCollection Data="@Data"
+ Columns="@Columns"
+ OnClick="@RefreshComponent"></RowCollection>
+ </CascadingValue>
+ </tbody>
+</table>
+
+
+@code {
+ [Parameter]
+ public WeatherForecast[] Data { get; set; }
+
+ [Parameter]
+ public List<string> Columns { get; set; }
+
+ DateTime t1;
+ DateTime t2;
+ Task RefreshComponent(int index)
+ {
+ t1 = DateTime.Now;
+ StateHasChanged();
+ return Task.CompletedTask;
+ }
+ protected override Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (!firstRender)
+ {
+ t2 = DateTime.Now;
+ Console.WriteLine("Refresh Time " + (t2 - t1).TotalMilliseconds);
+ }
+ return base.OnAfterRenderAsync(firstRender);
+ }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/FastGrid/Grid.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/FastGrid/Grid.razor
new file mode 100644
index 0000000000..0806655e31
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/FastGrid/Grid.razor
@@ -0,0 +1,48 @@
+@typeparam TRowData
+
+<CascadingValue IsFixed="true" Value="this">@ChildContent</CascadingValue>
+
+<table @attributes="@Attributes">
+ <thead>
+ <tr>
+ @foreach (var col in columns)
+ {
+ col.RenderHeader(__builder);
+ }
+ </tr>
+ </thead>
+ <tbody>
+ @foreach (var item in Data)
+ {
+ <tr @key="item.GetHashCode()" class="@(RowClass?.Invoke(item))">
+ @foreach (var col in columns)
+ {
+ col.RenderCell(__builder, item);
+ }
+ </tr>
+ }
+ </tbody>
+</table>
+
+@code {
+ [Parameter(CaptureUnmatchedValues = true)] public Dictionary<string, object> Attributes { get; set; }
+ [Parameter] public ICollection<TRowData> Data { get; set; }
+ [Parameter] public RenderFragment ChildContent { get; set; }
+ [Parameter] public Func<TRowData, string> RowClass { get; set; }
+
+ private List<GridColumn<TRowData>> columns = new List<GridColumn<TRowData>>();
+
+ internal void AddColumn(GridColumn<TRowData> column)
+ {
+ columns.Add(column);
+ }
+
+ protected override void OnAfterRender(bool firstRender)
+ {
+ if (firstRender)
+ {
+ // On the first render, we collect the list of columns, then we have to render them.
+ StateHasChanged();
+ }
+ }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/FastGrid/GridColumn.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/FastGrid/GridColumn.razor
new file mode 100644
index 0000000000..aa9c6cfd5b
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/FastGrid/GridColumn.razor
@@ -0,0 +1,23 @@
+@typeparam TRowData
+@using Microsoft.AspNetCore.Components.Rendering
+@code {
+ [CascadingParameter] public Grid<TRowData> OwnerGrid { get; set; }
+ [Parameter] public string Title { get; set; }
+ [Parameter] public TRowData RowData { get; set; }
+ [Parameter] public RenderFragment<TRowData> ChildContent { get; set; }
+
+ protected override void OnInitialized()
+ {
+ OwnerGrid.AddColumn(this);
+ }
+
+ internal void RenderHeader(RenderTreeBuilder __builder)
+ {
+ <th>@Title</th>
+ }
+
+ internal void RenderCell(RenderTreeBuilder __builder, TRowData rowData)
+ {
+ <td>@ChildContent(rowData)</td>
+ }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/MainLayout.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/MainLayout.razor
index acf8fd2f8a..8b4e64bb66 100644
--- a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/MainLayout.razor
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/MainLayout.razor
@@ -6,7 +6,8 @@
<a href="renderlist">RenderList</a> |
<a href="json">JSON</a> |
<a href="orgchart">OrgChart</a> |
-<a href="timer">Timer</a>
+<a href="timer">Timer</a> |
+<a href="gridrendering">Grid</a>
<hr />
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/Cell.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/Cell.razor
new file mode 100644
index 0000000000..913436fd99
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/Cell.razor
@@ -0,0 +1,30 @@
+@using WeatherForecast = Pages.GridRendering.WeatherForecast
+
+<td @onclick="@(() => OnClick.Invoke(1))">
+ @switch (Field)
+ {
+ case "Date":
+ @Item.Date.ToShortDateString()
+ break;
+ case "TemperatureC":
+ @Item.TemperatureC
+ break;
+ case "TemperatureF":
+ @Item.TemperatureF
+ break;
+ case "Summary":
+ @Item.Summary
+ break;
+ }
+</td>
+
+@code {
+ [Parameter]
+ public WeatherForecast Item { get; set; }
+
+ [Parameter]
+ public string Field { get; set; }
+
+ [Parameter]
+ public Func<int, Task> OnClick { get; set; }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/Row.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/Row.razor
new file mode 100644
index 0000000000..fc1b5c2f06
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/Row.razor
@@ -0,0 +1,35 @@
+@using WeatherForecast = Pages.GridRendering.WeatherForecast
+
+<tr style="@rowStyle">
+ @foreach (var item in Columns)
+ {
+ <Cell Item="@Item"
+ Field="@item"
+ OnClick="@OnCellClick">
+ </Cell>
+ }
+</tr>
+
+
+@code {
+
+ private bool isSelected = false;
+
+ private string rowStyle => isSelected ? "background-color: lightblue;" : "";
+
+ [Parameter]
+ public WeatherForecast Item { get; set; }
+
+ [Parameter]
+ public List<string> Columns { get; set; }
+
+ [Parameter]
+ public Func<int, Task> OnClick { get; set; }
+
+ Task OnCellClick(int args)
+ {
+ isSelected = !isSelected;
+
+ return OnClick.Invoke(args);
+ }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/RowCollection.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/RowCollection.razor
new file mode 100644
index 0000000000..180043c5c8
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/RowCollection.razor
@@ -0,0 +1,19 @@
+@using WeatherForecast = Pages.GridRendering.WeatherForecast
+
+@foreach (var item in Data)
+{
+ <Row Item="@item" Columns="@Columns"
+ OnClick="@OnClick"></Row>
+}
+
+
+@code {
+ [Parameter]
+ public WeatherForecast[] Data { get; set; }
+
+ [Parameter]
+ public List<string> Columns { get; set; }
+
+ [Parameter]
+ public Func<int, Task> OnClick { get; set; }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/TableComponent.razor b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/TableComponent.razor
new file mode 100644
index 0000000000..ea75beebc7
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/Shared/PlainTable/TableComponent.razor
@@ -0,0 +1,44 @@
+@using WeatherForecast = Pages.GridRendering.WeatherForecast
+
+<table class="table">
+ <thead>
+ <tr>
+ @foreach (var item in Columns)
+ {
+ <th>@item</th>
+ }
+ </tr>
+ </thead>
+ <tbody>
+ <RowCollection Data="@Data"
+ Columns="@Columns"
+ OnClick="@RefreshComponent"></RowCollection>
+ </tbody>
+</table>
+
+
+@code {
+ [Parameter]
+ public WeatherForecast[] Data { get; set; }
+
+ [Parameter]
+ public List<string> Columns { get; set; }
+
+ DateTime t1;
+ DateTime t2;
+ Task RefreshComponent(int index)
+ {
+ t1 = DateTime.Now;
+ StateHasChanged();
+ return Task.CompletedTask;
+ }
+ protected override Task OnAfterRenderAsync(bool firstRender)
+ {
+ if (!firstRender)
+ {
+ t2 = DateTime.Now;
+ Console.WriteLine("Refresh Time " + (t2 - t1).TotalMilliseconds);
+ }
+ return base.OnAfterRenderAsync(firstRender);
+ }
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/wwwroot/benchmarks/grid.js b/src/Components/benchmarkapps/Wasm.Performance/TestApp/wwwroot/benchmarks/grid.js
new file mode 100644
index 0000000000..3acd452ae0
--- /dev/null
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/wwwroot/benchmarks/grid.js
@@ -0,0 +1,105 @@
+import { group, benchmark, setup, teardown } from './lib/minibench/minibench.js';
+import { receiveEvent } from './util/BenchmarkEvents.js';
+import { BlazorApp } from './util/BlazorApp.js';
+import { setInputValue } from './util/DOM.js';
+
+group('Grid', () => {
+ let app;
+
+ setup(async () => {
+ app = new BlazorApp();
+ await app.start();
+ app.navigateTo('gridrendering');
+ });
+
+ teardown(() => {
+ app.dispose();
+ });
+
+ benchmark('PlainTable: From blank', () => measureRenderGridFromBlank(app), {
+ setup: () => prepare(app, 'PlainTable', false),
+ descriptor: {
+ name: 'blazorwasm/render-plaintable-from-blank',
+ description: 'Time to render plain table from blank (ms)'
+ }
+ });
+
+ benchmark('PlainTable: Switch pages', () => measureRenderGridSwitchPages(app), {
+ setup: () => prepare(app, 'PlainTable', true),
+ descriptor: {
+ name: 'blazorwasm/render-plaintable-switch-pages',
+ description: 'Time to render plain table change of page (ms)'
+ }
+ });
+
+ benchmark('ComplexTable: From blank', () => measureRenderGridFromBlank(app), {
+ setup: () => prepare(app, 'ComplexTable', false),
+ descriptor: {
+ name: 'blazorwasm/render-complextable-from-blank',
+ description: 'Time to render complex table from blank (ms)'
+ }
+ });
+
+ benchmark('ComplexTable: Switch pages', () => measureRenderGridSwitchPages(app), {
+ setup: () => prepare(app, 'ComplexTable', true),
+ descriptor: {
+ name: 'blazorwasm/render-complextable-switch-pages',
+ description: 'Time to render complex table change of page (ms)'
+ }
+ });
+
+ benchmark('FastGrid: From blank', () => measureRenderGridFromBlank(app), {
+ setup: () => prepare(app, 'FastGrid', false),
+ descriptor: {
+ name: 'blazorwasm/render-fastgrid-from-blank',
+ description: 'Time to render fast grid from blank (ms)'
+ }
+ });
+
+ benchmark('FastGrid: Switch pages', () => measureRenderGridSwitchPages(app), {
+ setup: () => prepare(app, 'FastGrid', true),
+ descriptor: {
+ name: 'blazorwasm/render-fastgrid-switch-pages',
+ description: 'Time to render fast grid change of page (ms)'
+ }
+ });
+});
+
+async function prepare(app, renderMode, populateTable) {
+ const renderModeSelect = app.window.document.querySelector('#render-mode');
+ setInputValue(renderModeSelect, renderMode);
+
+ if (populateTable) {
+ let nextRenderCompletion = receiveEvent('Finished rendering table');
+ app.window.document.querySelector(populateTable ? '#show' : '#hide').click();
+ await nextRenderCompletion;
+ }
+}
+
+async function measureRenderGridFromBlank(app) {
+ const appDocument = app.window.document;
+
+ let nextRenderCompletion = receiveEvent('Finished rendering table');
+ appDocument.querySelector('#hide').click();
+ await nextRenderCompletion;
+
+ if (appDocument.querySelectorAll('tbody tr').length !== 0) {
+ throw new Error('Wrong number of rows rendered');
+ }
+
+ nextRenderCompletion = receiveEvent('Finished rendering table');
+ appDocument.querySelector('#show').click();
+ await nextRenderCompletion;
+
+ if (appDocument.querySelectorAll('tbody tr').length !== 200) {
+ throw new Error('Wrong number of rows rendered');
+ }
+}
+
+async function measureRenderGridSwitchPages(app) {
+ const appDocument = app.window.document;
+
+ let nextRenderCompletion = receiveEvent('Finished rendering table');
+ appDocument.querySelector('#change-page').click();
+ await nextRenderCompletion;
+}
diff --git a/src/Components/benchmarkapps/Wasm.Performance/TestApp/wwwroot/benchmarks/index.js b/src/Components/benchmarkapps/Wasm.Performance/TestApp/wwwroot/benchmarks/index.js
index c69e1df192..cf923ae082 100644
--- a/src/Components/benchmarkapps/Wasm.Performance/TestApp/wwwroot/benchmarks/index.js
+++ b/src/Components/benchmarkapps/Wasm.Performance/TestApp/wwwroot/benchmarks/index.js
@@ -4,6 +4,7 @@ import './appStartup.js';
import './renderList.js';
import './jsonHandling.js';
import './orgChart.js';
+import './grid.js';
import { getBlazorDownloadSize } from './blazorDownloadSize.js';
new HtmlUI('E2E Performance', '#display');