Trial - boosting prospect grid loading performance

This commit is contained in:
troogs
2026-09-20 11:09:44 +02:00
parent 8b298b37c7
commit b33f9f6c52
15 changed files with 688 additions and 73 deletions
@@ -97,7 +97,9 @@ namespace FoodsharingSiegen.Server.Controls
/// <summary>
/// Gets the value of the interactions (ab)
/// </summary>
private List<Interaction> Interactions => Prospect?.Interactions.Where(x => x.Type == Type).ToList() ?? [];
private List<Interaction> Interactions => Prospect?.Interactions is null
? []
: [.. Prospect.Interactions.Where(x => x.Type == Type)];
/// <summary>
/// Gets the value of the not needed (ab)
@@ -1,4 +1,7 @@
@using FoodsharingSiegen.Contracts.Enums
@using Microsoft.JSInterop
@implements IAsyncDisposable
@inject IJSRuntime JSRuntime
@code {
[Parameter] public List<Prospect>? Prospects { get; set; }
@@ -7,19 +10,95 @@
[Parameter] public Func<Task>? OnDataChanged { get; set; }
[Parameter] public EventCallback OnLoadMore { get; set; }
[Parameter] public bool IsLoadingMore { get; set; }
[Parameter] public bool HasMore { get; set; }
[Parameter] public string GridClass { get; set; } = string.Empty;
private IJSObjectReference? _module;
private DotNetObjectReference<ProspectGrid>? _dotNetHelper;
private string _gridId = $"prospect-grid-{Guid.NewGuid():N}";
private bool _isJsBound;
private bool _disposed;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (_disposed || !firstRender || _isJsBound) return;
try
{
_dotNetHelper ??= DotNetObjectReference.Create(this);
_module ??= await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./js/prospect-grid.js");
await _module.InvokeVoidAsync("attachScrollLoader", _gridId, _dotNetHelper);
_isJsBound = true;
}
catch (JSDisconnectedException)
{
// Ignore browser disconnect during teardown.
}
catch (ObjectDisposedException)
{
// Ignore late render after the component is being torn down.
}
}
[JSInvokable]
public async Task OnScrollNearBottom()
{
if (OnLoadMore.HasDelegate && !IsLoadingMore && HasMore)
{
await OnLoadMore.InvokeAsync();
}
}
public async ValueTask DisposeAsync()
{
_disposed = true;
if (_module is not null)
{
try
{
await _module.InvokeVoidAsync("disposeScrollLoader", _gridId);
}
catch (JSDisconnectedException)
{
// ignored; the circuit is already disconnected
}
catch (ObjectDisposedException)
{
// ignored; the JS runtime is already disposed
}
}
_dotNetHelper?.Dispose();
_dotNetHelper = null;
_isJsBound = false;
}
}
<h6>@(Prospects?.Count ?? 0) Ergebnisse</h6>
@if (Prospects?.Any() == true)
{
<div class="prospect-grid @GridClass">
<Repeater Items="@Prospects">
<ProspectContainer
Prospect="context"
<div id="@_gridId" class="prospect-grid @GridClass" style="max-height: calc(100vh - 250px); overflow-y: auto;">
@foreach (var prospect in Prospects)
{
<ProspectContainer @key="prospect.Id"
Prospect="prospect"
OnDataChanged="@OnDataChanged"
StateFilter="StateFilter"></ProspectContainer>
</Repeater>
}
@if (IsLoadingMore)
{
<div class="d-flex justify-content-center py-3 text-muted">
<span class="me-2"><i class="fa-solid fa-spinner fa-spin"></i></span>
Weitere laden...
</div>
}
</div>
}