CommunityCodierung & Entwicklunggithub.com

to110i/perceived-performance

Sorgen Sie dafür, dass sich Web-UIs sofort anfühlen, selbst wenn Operationen Zeit brauchen – mit Skeleton-Screens, optimistischem UI, Ladezuständen und Navigations-Feedback.

Was ist perceived-performance?

Dieses Skill befähigt KI-Agenten, die wahrgenommene Performance (Perceived Performance) von Webanwendungen gezielt zu verbessern. Im Gegensatz zur reinen Messung der Ladezeit geht es darum, die Benutzeroberfläche so zu gestalten, dass sie sich für den Nutzer schnell anfühlt – durch sofortiges visuelles Feedback, parallele Datenabrufe und progressive Rendering-Techniken. Das Skill bietet eine strukturierte Anleitung, um typische Performance-Fallstricke in Frameworks wie Next.js und React zu identifizieren und zu beheben. Es enthält einen Entscheidungsleitfaden, der von konkreten Symptomen (z.B. leerer Bildschirm, träge Button-Reaktion) direkt zur passenden Technik führt – von Skeleton-Screens über Optimistic UI bis hin zu Suspense Streaming oder dynamischen Imports. Der Analyse-Workflow umfasst fünf Schritte: Erkennen des ersten visuellen Eindrucks, Klassifizierung der Daten nach Dringlichkeit, Behebung von Datenabhängigkeiten (z.B. parallele statt sequentielle `await`-Aufrufe), Anwendung progressiven Renderings und abschließende Validierung. Anti-Patterns wie sequentielle `await`-Ketten oder fehlendes Klick-Feedback werden explizit aufgedeckt. Ausgabeformat ist eine strukturierte Markdown-Antwort mit Ist-Zustand, Ursache, Änderungen, Implementierung und Hinweisen.

Funktioniert mit~Claude Code~Codex CLI~Cursor
npx skills add to110i/perceived-performance

Installed? Explore more Codierung & Entwicklung skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

In Ihrer bevorzugten KI fragen

Öffnet einen neuen Chat, in dem dieser Agent-Skill bereits geladen ist.

Dokumentation

Progressive Web-UI

Bei der wahrgenommenen Performance (Perceived Performance) geht es darum, dass sich die UI schnell anfühlt, nicht nur darum, dass sie gemessen schnell ist. Eine Seite, die in 2s lädt, aber sofort ein Skelett anzeigt, fühlt sich schneller an als eine, die in 1,5s lädt, aber die ganze Zeit einen leeren Bildschirm zeigt.

Wenn der Benutzer Code teilt:

  1. Lies ihn, um zu verstehen, was Benutzer aktuell während Lade- und Wartezuständen sehen
  2. Identifiziere mithilfe des untenstehenden Entscheidungsleitfadens, welche Technik(en) zutreffen
  3. Erkläre was geändert werden muss, warum es die wahrgenommene Geschwindigkeit verbessert und wie es mit konkretem Code umgesetzt wird

Kernprinzipien

1. Trenne „erste Ansicht“ von allem anderen

Unterscheide immer:

  • Was für den ersten Paint erforderlich ist
  • Was geladen werden kann, nachdem das Shell sichtbar ist
  • Was auf Benutzerinteraktion warten kann

Behandle nicht alle Daten als gleich dringend.

2. Struktur vor Daten

Das Seiten-Shell (Layout, Nav-Slots, Header-Rahmen) sollte an den Browser gesendet werden, bevor ein Datenabruf abgeschlossen ist. Benutzer bilden ihren Geschwindigkeitseindruck in den ersten 100–200 ms. Das sofortige Zeigen der Struktur reduziert die gefühlte Wartezeit, selbst wenn die tatsächliche Ladezeit identisch ist.

3. Lasse nie einen Klick unbeantwortet

Jede Interaktion (Klick, Tippen, Navigation) muss im ersten Frame eine sichtbare Reaktion hervorrufen. Wenn die eigentliche Operation Zeit braucht, zeige sofort einen Zwischenzustand an.

4. Behebe die Struktur, nicht nur das Lade-UI

loading.tsx und Skelette verbessern das Erscheinungsbild, beheben aber nicht das Über-Abrufen oder sequentielle Datenabhängigkeiten. Gehe immer der Ursache auf den Grund:

  • Sequentielle await-Ketten → parallelisieren mit Promise.all
  • Einzelner großer Abruf → aufteilen in Erstansicht vs. zurückgestellt
  • Vollständiges Profil bei Navigation → leichten Navigations-Identitätshelfer verwenden

5. Navigation muss sich auch schnell anfühlen

Die wahrgenommene Geschwindigkeit betrifft nicht nur den Erstladevorgang. Seitenübergänge, wiederholte Besuche und Interaktionen müssen sich gleichermaßen schnell anfühlen:

  • Prefetch-Routen, bevor der Benutzer klickt
  • loading.tsx sofort bei Navigationsstart anzeigen
  • SWR/Cache für sofortige Wiederholungsbesuche nutzen

Entscheidungsleitfaden

SymptomTechnik
Leerer Bildschirm während Daten ladenSkeleton-Screens / Suspense Streaming
Button-Klick hat keine sofortige ReaktionOptimistisches UI / sofortiges Feedback
Seitenübergang startet nach Klick nicht visuellloading.tsx + Prefetch
Schweres Komponente verlangsamt initiales RendernDynamischer Import
Spinner erscheint bei jedem Besuch derselben DatenSWR Stale-While-Revalidate
Eine langsame API blockiert eine gesamte SeiteSuspense Streaming (parallele async Server Components)
Auth/Profile-Abruf verzögert Navigation oder Seiten-ShellAuth-Layout-Trennung (siehe references/auth-performance.md)
Bilder verursachen Layout-Verschiebungen oder fühlen sich langsam annext/image mit priority / blur-Platzhalter
Schriftartwechsel verursacht Flash of Unstyled Textnext/font
Formularabsendung hat kein visuelles FeedbackuseFormStatus / useActionState
Lange Liste verursacht Scroll-Ruckeln oder langsames RendernVirtuelles Scrollen (TanStack Virtual / react-window)
Nicht dringender Zustandswechsel blockiert BenutzereingabestartTransition für verzögertes Rendern

Analyse-Workflow

Schritt 1: Identifiziere, was Benutzer zuerst sehen

Was rendert in 0–200 ms? Wenn es leer oder ein Spinner ist, sind strukturelle Änderungen nötig, bevor Styling-Fixes helfen.

Schritt 2: Klassifiziere Daten nach Dringlichkeit

  1. Erste Ansicht – muss vorhanden sein, damit die Seite sinnvoll ist
  2. Zurückgestellt – kann nach dem Shell sichtbar hereinströmen
  3. Auf Abruf – nur nach Benutzerinteraktion laden

Schritt 3: Behebe Datenabhängigkeiten

  • Sequentielle await → Promise.all oder separate async Server Components
  • Über-Abrufen beim initialen Laden → API aufteilen oder paginieren
  • Vollständiges Profil bei Navigation → separaten Navigations-Identitätshelfer

Schritt 4: Wende progressives Rendern an

Wähle basierend darauf, was benötigt wird:

  • loading.tsx – sofortiges Navigations-Skelett (ganze Seite)
  • <Suspense> – granuläres Streaming (pro Abschnitt)
  • useOptimistic – sofortiges Mutations-Feedback
  • dynamic() – schweres Komponentenbündel zurückstellen
  • SWR – sofortige Wiederholungsbesuche aus dem Cache

Schritt 5: Validiere die wahrgenommene Performance

  • Erscheint sofort etwas Sinnvolles (< 200 ms)?
  • Wird der Benutzer während aller Ladezustände informiert?
  • Ist die UI reaktionsfähig, bevor alle Daten ankommen?
  • Erzeugt die Interaktion im ersten Frame Feedback?

Ausgabeformat

Wenn du dieses Skill anwendest, antworte in dieser Struktur:

## Was gerade passiert
- [beschreibe, was Benutzer aktuell erleben]

## Ursache
- [was im Code das langsame Gefühl verursacht]

## Was geändert werden muss und warum
- [Änderung 1]: [warum dies die wahrgenommene Geschwindigkeit verbessert]
- [Änderung 2]: ...

## Implementierung

[code]

## Hinweise
- [eventuelle Einschränkungen, Randfälle oder Folgeverbesserungen]

Referenzen

Ausführliche Implementierungsdetails mit vollständigen Codebeispielen findest du in:

  • references/nextjs-patterns.md – Skeleton-Screens, Optimistisches UI, Suspense Streaming, Prefetch, Dynamischer Import, SWR, Bilder, Schriften, Interaktions-Feedback, useFormStatus, Virtuelles Scrollen, startTransition
  • references/auth-performance.md – Auth-Layout-Trennung, Navigations-Identitätshelfer, Request/Process-Warm-Up, Fallback-Zustandsdesign

Lese die entsprechende Referenz, wenn du eine bestimmte Technik implementierst.


Anti-Patterns zum Beheben

Erkenne und behebe immer:

  • Abrufen des vollständigen Profils/Auth im Top-Level-Layout → verzögert jede Seite
  • Sequentielle await-Ketten für unabhängige Daten → unnötige Serialisierung
  • loading.tsx hinzugefügt, ohne das zugrundeliegende Über-Abrufen zu beheben
  • Rendern vollständiger Datensätze beim initialen Laden → paginieren oder virtualisieren
  • Kein visuelles Feedback bei Klick, bis die Operation abgeschlossen ist → sofort bestätigen
  • Unterschiedliche Auth-Quellen in Navigation vs. Seite → kanonische Inkonsistenz des Benutzernamens
  • Formular-Absendestatus nur nach Serverantwort verwalten → useFormStatus für sofortigen Wartezustand nutzen
  • Rendern aller Elemente einer langen Liste beim Mount → virtualisieren (nur sichtbare Zeilen rendern)
  • Teure Zustandsänderung (Filter/Sortieren/Suche) blockiert Benutzereingabe → in startTransition einwickeln

Verwandte Skills