Ihre Blazor-App ist langsam? 7 Ursachen und wie Sie sie beheben

Die Blazor-App hakt beim Klick, eine Tabelle friert ein oder der Serverspeicher wächst? Die sieben häufigsten Ursachen, mit Code vorher und nachher.

Vlado Pandžić

Vlado Pandžić · Gründer · Senior .NET-Architekt
Veröffentlicht · 4 Min. Lesezeit

Am Anfang fliegt eine Blazor-Anwendung. Ein paar Bildschirme, wenig Daten, alles reagiert sofort. Ein Jahr später hakt ein Klick, die Bestelltabelle friert für ein paar Sekunden ein, und der Server braucht im Laufe des Tages immer mehr Speicher.

Blazor ist selten allein schuld. Fast immer ist es eine dieser sieben Ursachen, und alle lassen sich beheben, ohne die Anwendung neu zu schreiben. Jede steht hier mit Code, für .NET 10.

Zuerst: Messen Sie, was gerendert wird

Die häufigste Überraschung ist, wie oft eine Komponente rendert. Ein temporäres Log zeigt es in einer Minute:

protected override void OnAfterRender(bool firstRender)
    => Logger.LogDebug("{Component} rendered", GetType().Name);   // temporär, nur während der Messung

Wenn ein Klick fünfzig Zeilen ins Log schreibt, haben Sie Problem Nummer eins gefunden.

1. Alles rendert bei jedem Klick neu

Blazor rendert ein Kind neu, wenn sich seine Parameter ändern. Ist ein Parameter aber ein komplexes Objekt, etwa eine ganze Bestellung, kann Blazor nicht wissen, ob sich darin etwas geändert hat, und rendert jedes Mal. Einfache Typen wie int und string lösen kein neues Rendern aus, solange sich ihr Wert nicht ändert.

@* vorher: das ganze Objekt, also rendert die Zeile bei jeder Änderung des Elternteils *@
<OrderRow Order="order" />

@* nachher: nur das, was die Zeile anzeigt *@
<OrderRow Number="@order.Number" Customer="@order.CustomerName" Total="@order.Total" />

Wenn das nicht möglich ist, kann die Komponente selbst entscheiden, ob sie rendert:

private int lastVersion;

protected override bool ShouldRender()
{
    var changed = Order.Version != lastVersion;   // nur rendern, wenn sich die Bestellung wirklich geändert hat
    lastVersion = Order.Version;
    return changed;
}

2. Listen ohne @key

Ändert sich eine Liste, vergleicht Blazor ohne @key die Zeilen nach Position. Eine oben eingefügte Zeile bedeutet, dass alle Zeilen darunter neu rendern, und Zustand innerhalb der Zeilen kann in der falschen Zeile landen.

@foreach (var order in orders)
{
    <OrderRow @key="order.Id" Number="@order.Number" Total="@order.Total" />
}

3. Tabellen mit Tausenden Zeilen

Fünftausend auf einmal gerenderte Zeilen bedeuten fünftausend Komponenten im Speicher und auf dem Bildschirm, obwohl der Nutzer zwanzig davon sieht. Virtualize rendert nur, was sichtbar ist:

<Virtualize Items="orders" Context="order">
    <OrderRow @key="order.Id" Number="@order.Number" Total="@order.Total" />
</Virtualize>

QuickGrid macht dasselbe mit Virtualize="true", und für wirklich große Datenmengen können beide die Zeilen stückweise vom Server holen.

4. Daten werden zweimal geladen

Mit Prerendering läuft OnInitializedAsync zweimal: einmal auf dem Server für die erste Anzeige und noch einmal, wenn die Komponente interaktiv wird. Das bedeutet zwei identische Datenbankabfragen und ein Flackern auf dem Bildschirm. In .NET 10 löst das ein einziges Attribut:

@code {
    [PersistentState]
    public List<OrderSummary>? Orders { get; set; }

    protected override async Task OnInitializedAsync()
    {
        Orders ??= await OrderService.GetOpenAsync();   // beim zweiten Mal sind die Daten schon da
    }
}

5. StateHasChanged zu oft

Eine Komponente, die Preise, Status oder Nachrichten in Echtzeit verfolgt, kommt schnell auf Dutzende Renderings pro Sekunde. Der Nutzer sieht keinen Unterschied zwischen 4 und 40 Aktualisierungen pro Sekunde, Server und Browser aber sehr wohl.

protected override void OnInitialized()
{
    Prices.Changed += OnPriceChanged;
    renderTimer = new Timer(_ =>
    {
        if (!dirty) return;
        dirty = false;
        InvokeAsync(StateHasChanged);                  // höchstens vier Renderings pro Sekunde
    }, null, 250, 250);
}

private void OnPriceChanged(object? sender, PriceChangedEventArgs e) => dirty = true;  // nur die Änderung vermerken

6. Serverspeicher, der nur wächst

Eine Komponente, die ein Event abonniert oder einen Timer startet und das nie beendet, stirbt nie. Bei Blazor Server heißt das: Der Speicher wächst mit jedem Nutzer und jedem geöffneten Bildschirm, bis zum nächsten Neustart.

@implements IDisposable

@code {
    public void Dispose()
    {
        Prices.Changed -= OnPriceChanged;              // ohne das bleibt die Komponente im Speicher
        renderTimer?.Dispose();
    }
}

7. Der falsche Rendermodus für den Bildschirm

In .NET 10 kann jede Seite ihren eigenen Rendermodus haben. Interactive Server ist hervorragend für interne Bildschirme in einem guten Netzwerk, aber bei einer schlechten Verbindung wartet jeder Klick auf das Netz. Seiten, die nur gelesen werden, brauchen gar keine Interaktivität.

@* MonthlyReport.razor: nur lesen, statisches Rendering ohne Verbindung zum Server *@
@page "/reports/monthly"

@* Orders.razor: ein interaktiver Bildschirm *@
@page "/orders"
@rendermode InteractiveServer

Welcher Modus für welchen Bildschirm, steht in der Tabelle auf der Seite Blazor-Spezialisierung.

In welcher Reihenfolge

  1. MessenWie oft was rendert
  2. AufteilenKleinere Komponenten, einfache Parameter
  3. VirtualisierenGroße Listen und Tabellen
  4. AufräumenDispose und Rendermodus

Oft ist ein langsamer Blazor-Bildschirm gar kein Blazor-Problem, sondern ein Problem der Abfragen dahinter. Wenn ein Bildschirm lange lädt, aber wenig rendert, lesen Sie den Artikel über EF-Core-Performance.

Wie wir arbeiten

ProCoding ist ein .NET-Studio aus Split, Kroatien, und wir bringen Blazor seit 2020 in Produktion, von Software für den Bau von Elektroautos bis zur Steuerung von Batteriespeichern. Ein Blazor Health Check findet, welche dieser Ursachen Ihre Anwendung bremst, und liefert eine priorisierte Liste von Korrekturen. Der erste Schritt ist ein kostenloses 30-minütiges Gespräch.

Quellen

Dieser Artikel dient nur der allgemeinen Information und ist keine Rechts-, Steuer-, Finanz- oder sonstige Fachberatung. Szenarien, Beispiele und Berechnungen dienen der Veranschaulichung. Nutzungsbedingungen und Haftungsausschluss.

Verwandte Artikel

© 2026 ProCoding — Alle Rechte vorbehalten.Impressum und DatenschutzHaftungsausschlussSplit, Kroatien