Der Cache

Registriere AddDeja() und jede Query mit Key nutzt einen gemeinsamen, app-weiten Cache: sofortiges Rendern aus gecachten Daten, ein Fetch pro Key — egal wie viele Komponenten anfragen — und Revalidierung im Hintergrund, wenn Daten stale werden.

Aktivieren#

Program.cs
builder.Services.AddDeja(options =>
{
    options.DefaultStaleTime = TimeSpan.FromSeconds(10); // fresh window: no refetch on mount
    options.DefaultCacheTime = TimeSpan.FromMinutes(5);  // unsubscribed entry lifetime
});

Queries nehmen pro Ausführung teil, indem sie einen Key setzen; eine Query ohne Key berührt den Cache nie. Komponenten, die von DejaComponentBase erben, bekommen den Client automatisch an ihre Queries gereicht — außerhalb einer Komponente übergibst du ihn über den Query<T>(DejaClient)-Konstruktor oder QueryParameters<T>.Client.

Was ein Execute mit Key tut#

  1. Hat der Eintrag Daten, rendert er sofort (IsCachedData ist true) — kein Lade-Flackern.
  2. Die Aktualität entscheidet, ob im Hintergrund neu geladen wird: Mit der DefaultStaleTime dieser Seite von 10 Sekunden werden jüngere Daten ganz ohne Request ausgeliefert.
  3. Parallele Ausführungen mit demselben Key — aus beliebigen Komponenten — schließen sich einem laufenden Fetch an.
  4. Trifft das Ergebnis ein, benachrichtigt der Eintrag jede abonnierte Query, und jede benachrichtigt ihre eigene Komponente. Ein Codepfad für alle Subscriber — zwei Komponenten mit demselben Key können also nicht auseinanderlaufen.

Lebenszyklus und Verdrängung von Einträgen#

Ein Eintrag mit aktiven Subscribern wird nie verdrängt. Wenn der letzte Subscriber unmountet, beginnt die Verdrängungsuhr zu laufen: Der Eintrag überlebt die effektive Cache-Zeit (Standard 5 Minuten), sodass eine Komponente, die innerhalb dieses Fensters erneut mountet, ihre Daten sofort bekommt. Eine optionale MaxEntries-Obergrenze verdrängt am längsten unbenutzte Einträge ohne Subscriber vorzeitig.

Direkt lesen und schreiben#

DejaClient ist auch eine manuelle Schnittstelle: GetData / TryGetData zum Nachsehen, SetData zum Schreiben (siehe die Demo zum optimistischen Schreiben), InvalidateAsync, um als stale zu markieren und neu zu laden, Remove / Clear, um Einträge zu entfernen. Die vollständige Schnittstelle steht in der API-Referenz.

Ein Key, ein Typ

Ein Key speichert einen Datentyp. Lesen mit dem falschen Typ (TryGetData) gibt false zurück und loggt eine Debug-Warnung; eine Query gegen einen Key auszuführen, der bereits einen anderen Typ hält, wirft eine Exception — wenn zwei Aufrufstellen sich über die Form eines Keys uneinig sind, ist das ein Bug, den stilles Ersetzen verschleiern würde.

Blazor Server: Scoped ist nicht verhandelbar

Der Client ist Scoped registriert: pro Browser-Tab auf WebAssembly, pro User-Circuit auf dem Server. Ihn auf Blazor Server zu einem Singleton zu „optimieren“ würde die gecachten API-Antworten eines Users mit jedem anderen User teilen.

Live-Demo#

Sofortiges Rendern beim erneuten Mounten

Remountable component renders: 4

State IsLoading IsReFetching IsError IsCachedData IsStale ReFetchCount: 1UpdatedAt: 20:33:33
  • delectus aut autem
  • quis ut nam facilis et officia qui
  • fugiat veniam minus
  • et porro tempora
  • laboriosam mollitia et enim quasi adipisci quia provident illum
Key Data Fetching Invalidated Subscribers Updated
["todos","list",5] · · 1 20:33:33

Unmounting drops the subscriber count to zero, which starts the entry's eviction clock (5 minutes here). Remounting within the site's 10-second stale time serves the cache with no request at all; after that, it still renders instantly and refetches in the background.

<div class="demo-toolbar">
    <button class="demo-button primary" @onclick="() => _mounted = !_mounted">
        @(_mounted ? "Unmount component" : "Mount component")
    </button>
</div>

@if (_mounted)
{
    <SharedCachePanel Title="Remountable component"/>
}
else
{
    <p class="demo-note">Component unmounted. The cache entry survives below — remount within the
        cache time and the data renders instantly, then revalidates in the background if stale.</p>
}

<CacheInspector Keys="@(new[] { DocsKeys.TodoList(5) })"/>

<p class="demo-note">
    Unmounting drops the subscriber count to zero, which starts the entry's eviction clock
    (5 minutes here). Remounting within the site's 10-second stale time serves the cache with no
    request at all; after that, it still renders instantly and refetches in the background.
</p>

@code {
    private bool _mounted = true;
}