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#
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#
- Hat der Eintrag Daten, rendert er sofort (
IsCachedDataist true) — kein Lade-Flackern. - Die Aktualität entscheidet, ob im Hintergrund neu geladen wird: Mit der
DefaultStaleTimedieser Seite von 10 Sekunden werden jüngere Daten ganz ohne Request ausgeliefert. - Parallele Ausführungen mit demselben Key — aus beliebigen Komponenten — schließen sich einem laufenden Fetch an.
- 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 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.
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#
Remountable component renders: 4
- 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;
}