Fix #3: Suche fühlt sich träge an — Rückmeldung beim Tippen #11

Merged
florian.wilde merged 1 commits from fix/3-suche-rueckmeldung into main 2026-09-02 04:33:28 +00:00
Owner

Die Bibliotheksfilterleiste erzeugte das Ladesignal längst und warf es weg: const [, startTransition] = useTransition(). Während der Suche blieben die alten Treffer unverändert stehen, ohne jeden Hinweis, dass gearbeitet wird.

Was geändert wurde

  • SearchPending — eine schmale Klammer, die beide Suchen teilen. Die Filterleiste meldet den Ladezustand, die Trefferliste daneben (eine Server-Komponente) wird gedämpft und auf aria-busy gesetzt.
  • Die alten Treffer bleiben sichtbar. Sie verschwinden zu lassen ließe die Liste bei jedem Tastendruck springen; gedämpft und nicht anklickbar ist aber sichtbar „nicht mehr aktuell".
  • Der Hinweis „sucht …" steht jetzt auch in der Bibliothek, nicht nur unter /suche.
  • Sammelverzögerung in beiden auf 250 ms angeglichen (vorher 350 und 300).

Zwei Vermutungen aus dem Issue haben sich nicht bestätigt

Ich habe sie gemessen, statt sie zu beheben — beide bleiben deshalb unangetastet.

Die Facetten kosten nichts. Gemessen an einer eigens angelegten Bibliothek mit 2000 Einträgen (Median aus 9 Läufen):

getLibrary() mit Suchbegriff 50 ms
getLibraryFacets() 17 ms
beide parallel (wie die Seite) 61 ms

Sie laufen bereits in einem Promise.all und sind die schnellere Hälfte. Ein Wegfall spärte rund 12 ms — eine Zwischenspeicherung brächte dafür das Risiko veralteter Zähler. Die Annahme „bei einer großen Bibliothek deutlich mehr" trifft nicht zu: DISTINCT unnest bleibt auch bei 2000 Einträgen bei 17 ms.

Langsame Bilder blockieren die Trefferanzeige nicht. Mit künstlich um 1500 ms verzögerten /api/image-Antworten:

Treffer im DOM nach 465 ms (7 Stück)
alles inkl. Bilder nach 1356 ms

Der Text steht 891 ms vor den Bildern, und die Rückfallkacheln zeigen derweil die Titel — der Rückfall liegt dauerhaft unter dem <img>. Ein Umbau des Bild-Endpunkts wäre Aufwand ohne Wirkung, und die Weiterleitungsvariante hätte die Eigenschaft gekostet, dass die Instanz keine Fremdanfragen des Browsers auslöst.

Geprüft

Gegen einen Produktionsbau, mit künstlich gebremster Serverantwort:

Bibliothek Suche
aria-busy vorher/während/danach false / true / false false / true / false
„sucht …" sichtbar ja ja
Deckkraft der Treffer währenddessen 0.45 0.45

59 Tests grün, Typecheck sauber.

Offen bleibt der erste Abnahmepunkt

Die Messung am Produktivsystem kann ich nicht beisteuern. Wenn du im Netzwerk-Tab einmal tippst und die Dauer der Navigationsanfrage mit der der /api/image-Anfragen vergleichst, wissen wir, ob nach diesem PR noch etwas übrig ist. Meine Messungen hier sagen: die Datenbank ist es nicht, die Facetten sind es nicht, und die Bilder halten die Treffer nicht auf. Bleibt die Serverrunde je Eingabe — und die ist bei einer Instanz über das Internet vor allem Leitungsweg.

Closes #3

Die Bibliotheksfilterleiste erzeugte das Ladesignal längst und warf es weg: `const [, startTransition] = useTransition()`. Während der Suche blieben die alten Treffer unverändert stehen, ohne jeden Hinweis, dass gearbeitet wird. ## Was geändert wurde - **`SearchPending`** — eine schmale Klammer, die beide Suchen teilen. Die Filterleiste meldet den Ladezustand, die Trefferliste daneben (eine Server-Komponente) wird gedämpft und auf `aria-busy` gesetzt. - Die alten Treffer bleiben **sichtbar**. Sie verschwinden zu lassen ließe die Liste bei jedem Tastendruck springen; gedämpft und nicht anklickbar ist aber sichtbar „nicht mehr aktuell". - Der Hinweis **„sucht …"** steht jetzt auch in der Bibliothek, nicht nur unter `/suche`. - Sammelverzögerung in beiden auf **250 ms** angeglichen (vorher 350 und 300). ## Zwei Vermutungen aus dem Issue haben sich nicht bestätigt Ich habe sie gemessen, statt sie zu beheben — beide bleiben deshalb unangetastet. **Die Facetten kosten nichts.** Gemessen an einer eigens angelegten Bibliothek mit **2000 Einträgen** (Median aus 9 Läufen): | | | |---|---| | `getLibrary()` mit Suchbegriff | 50 ms | | `getLibraryFacets()` | 17 ms | | beide parallel (wie die Seite) | 61 ms | Sie laufen bereits in einem `Promise.all` und sind die schnellere Hälfte. Ein Wegfall spärte rund **12 ms** — eine Zwischenspeicherung brächte dafür das Risiko veralteter Zähler. Die Annahme „bei einer großen Bibliothek deutlich mehr" trifft nicht zu: `DISTINCT unnest` bleibt auch bei 2000 Einträgen bei 17 ms. **Langsame Bilder blockieren die Trefferanzeige nicht.** Mit künstlich um 1500 ms verzögerten `/api/image`-Antworten: | | | |---|---| | Treffer im DOM nach | **465 ms** (7 Stück) | | alles inkl. Bilder nach | 1356 ms | Der Text steht **891 ms vor den Bildern**, und die Rückfallkacheln zeigen derweil die Titel — der Rückfall liegt dauerhaft unter dem `<img>`. Ein Umbau des Bild-Endpunkts wäre Aufwand ohne Wirkung, und die Weiterleitungsvariante hätte die Eigenschaft gekostet, dass die Instanz keine Fremdanfragen des Browsers auslöst. ## Geprüft Gegen einen Produktionsbau, mit künstlich gebremster Serverantwort: | | Bibliothek | Suche | |---|---|---| | `aria-busy` vorher/während/danach | false / **true** / false | false / **true** / false | | „sucht …" sichtbar | ja | ja | | Deckkraft der Treffer währenddessen | 0.45 | 0.45 | 59 Tests grün, Typecheck sauber. ## Offen bleibt der erste Abnahmepunkt Die Messung **am Produktivsystem** kann ich nicht beisteuern. Wenn du im Netzwerk-Tab einmal tippst und die Dauer der Navigationsanfrage mit der der `/api/image`-Anfragen vergleichst, wissen wir, ob nach diesem PR noch etwas übrig ist. Meine Messungen hier sagen: die Datenbank ist es nicht, die Facetten sind es nicht, und die Bilder halten die Treffer nicht auf. Bleibt die Serverrunde je Eingabe — und die ist bei einer Instanz über das Internet vor allem Leitungsweg. Closes #3
florian.wilde added 1 commit 2026-09-01 22:23:36 +00:00
Rueckmeldung beim Tippen in beiden Suchen
CI / pruefen (pull_request) Canceled after 0s
d04248bec9
Die Bibliotheksfilterleiste erzeugte das Signal laengst und warf es weg:
`const [, startTransition] = useTransition()`. Waehrend der Suche blieben die
alten Treffer unveraendert stehen — ohne jeden Hinweis, dass gearbeitet wird.

Beide Suchen teilen sich jetzt eine schmale Klammer (SearchPending): die
Filterleiste meldet den Ladezustand, die Trefferliste daneben — eine
Server-Komponente — wird gedaempft und auf aria-busy gesetzt. Die alten
Treffer bleiben sichtbar; sie verschwinden zu lassen liesse die Liste bei
jedem Tastendruck springen. Der Hinweis „sucht …" steht jetzt auch in der
Bibliothek, nicht nur unter /suche.

Sammelverzoegerung in beiden auf 250 ms angeglichen (vorher 350 und 300).

Zwei Vermutungen aus dem Issue haben sich beim Nachmessen NICHT bestaetigt
und bleiben deshalb unangetastet:

Die Facetten kosten nichts. Gemessen an einer eigens angelegten Bibliothek
mit 2000 Eintraegen (Median aus 9 Laeufen): getLibrary 50 ms,
getLibraryFacets 17 ms, beide parallel 61 ms. Ein Wegfall spaerte rund 12 ms
— eine Zwischenspeicherung braechte dafuer das Risiko veralteter Zaehler.

Langsame Bilder blockieren die Trefferanzeige nicht. Mit kuenstlich um
1500 ms verzoegerten /api/image-Antworten stehen die Treffer nach 465 ms im
DOM, 891 ms vor den Bildern; die Rueckfallkacheln zeigen derweil die Titel.
Ein Umbau des Bild-Endpunkts waere also Aufwand ohne Wirkung.

Refs #3
florian.wilde merged commit 58a1d177df into main 2026-09-02 04:33:28 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: florian.wilde/flimmer#11