webv0.1.0betaMIT

Perf Budget Check

Prüft, wie schwer eine Seite tatsächlich lädt – ohne zu behaupten, damit LCP oder CLS zu messen.

Das Problem

Ein Performance-Budget hat zwei Hälften: Nutzer-Metriken wie LCP, die einen echten Browser brauchen, und Ressourcengewicht, das aus HTTP-Antworten ableitbar ist. Die meisten Werkzeuge vermischen beide oder behaupten, mit einem HTTP-Request Web Vitals zu messen.

Installation

Der Skill ist eine SKILL.md mit Referenztexten und abhängigkeitsfreien Node-Scripts – nichts davon ist an einen Anbieter gebunden. Wähle deinen Agenten:

Schritt 1

git clone https://github.com/larsdecker/agents-skills

Schritt 2

node agents-skills/install.mjs --agent cursor --skill perf-budget-check --target .

Statt cursor auch copilot, windsurf, cline, gemini oder agents (für Codex, Zed, Amp, opencode). Sinnvoll zusammen mit --skill perf-budget-fix.

Getestet mit: Claude Code, Cursor, GitHub Copilot, Codex, Windsurf, Cline, Gemini CLI, Zed. Ein hier nicht genannter Agent funktioniert ebenfalls – Skill-Verzeichnis ablegen und in der Anweisungsdatei des Agenten darauf verweisen.

Was dabei herauskommt

  • Befunde in drei Stufen: Budget-Verstöße, Lade-Strategie, Feinschliff
  • Reale Transferbytes statt eines oft fehlenden Content-Length-Headers
  • Explizite Liste, was nur ein echter Browser oder Felddaten zeigen können

Was er nicht tut

  • Keine LCP-, INP-, CLS- oder TBT-Messung – dafür braucht es Lighthouse oder Felddaten
  • Keine Bildattribut-Prüfung (width/height, loading, alt) – das übernimmt seo-check
  • Keine vollständige Request-Waterfall – nur was im initialen HTML referenziert ist
  • Keine Erfolgsgarantie für echte Nutzererfahrung

Zwei Budgets, ein Missverständnis

„Performance Budget" klingt nach einer Zahl. Tatsächlich sind es zwei völlig verschiedene Zahlenarten. Die eine Hälfte sind nutzerzentrierte Metriken — LCP, INP, CLS, TBT —, die beschreiben, wie sich eine Seite anfühlt. Sie lassen sich nur mit einem echten Browser oder mit Felddaten aus dem Chrome UX Report messen. Kein HTTP-Request kann simulieren, wie lange ein Hauptthread blockiert ist.

Die andere Hälfte ist Ressourcengewicht — Kilobyte JavaScript, Kilobyte CSS, Anzahl Requests, Anzahl Drittanbieter-Origins. Das lässt sich aus HTTP-Antworten ableiten, ganz ohne Browser.

Ein Werkzeug, das beide vermischt und am Ende einen LCP-Wert ausgibt, den es nie gemessen hat, verkauft eine Schätzung als Messung. Dieser Skill misst ausschließlich die zweite Hälfte — und sagt bei jedem Befund, in welche der beiden Kategorien er fällt.

Der Header, der einfach nicht da ist

Der naheliegende Ansatz für ein Byte-Budget ist, den Content-Length-Header abzufragen. Der erste Testlauf gegen die eigene, hinter Cloudflare liegende Website zeigte, warum das nicht reicht:

JS (Stichprobe):   0 KB
CSS (Stichprobe):  0 KB

Ein curl -I auf denselben Chunk bestätigte den Grund: Weder die HEAD- noch die GET-Antwort enthält einen Content-Length. Cloudflare streamt Brotli-komprimierte Antworten, ohne die Gesamtgröße vorher zu kennen — ein in der Praxis verbreitetes Verhalten bei modernen CDNs, das jedes Werkzeug unterläuft, das sich auf diesen Header verlässt.

Die Lösung war, den Header zu ignorieren und stattdessen selbst zu zählen: ein rohes GET über node:https, ohne automatische Dekomprimierung, das jedes empfangene Byte aufsummiert. Das ist zugleich die genauere Zahl — sie zeigt die tatsächliche Transfergröße, nicht das, was ein Header behauptet.

Was danach ein reales Ergebnis lieferte

Derselbe Scan gegen die Startseite:

JS (Stichprobe):   248 KB
Budget:            200 KB

Ein echter Budget-Verstoß von 48 KB, der vorher als „0 KB, alles im grünen Bereich" erschienen wäre. Genau dieser Unterschied — zwischen einem Header, der nicht da ist, und einer Zahl, die zählt — entscheidet, ob ein Scan nützlich ist oder nur beruhigend aussieht.

Wo die Zuständigkeit endet — bewusst

Ein Bild ohne width/height ist ein bekannter CLS-Auslöser. Ein lazy geladenes Hero-Bild ist ein bekannter LCP-Auslöser. Beide prüft SEO Check bereits, weil sie Bild-Tags betreffen und dort die Auffindbarkeits- und Renderings-Prüfung ohnehin ansetzt.

Dieser Skill wiederholt das nicht. Zwei Skills, die dasselbe <img>-Tag mit unterschiedlichen Schwellwerten oder Formulierungen bewerten, können sich widersprechen — und ein widersprüchlicher Befund kostet mehr Vertrauen, als er an Zusatzinformation bringt. Stattdessen arbeitet dieser Skill eine Ebene höher: Gesamtgewicht, Ladereihenfolge, Kompression, Caching, Drittanbieter-Zahl.

Was ausdrücklich nicht behauptet wird

Am Ende jedes Berichts steht, was der Scan nicht gemessen hat:

  • LCP, INP, CLS, TBT — brauchen Lighthouse oder Felddaten (RUM, CrUX). Der Scan nennt nur die bekannten Auslöser.
  • Vollständige Request-Waterfall — nur, was im initialen HTML referenziert ist. Was JavaScript zur Laufzeit nachlädt (Client-Routing, dynamische Imports), sieht der Scan nicht.
  • „Above the fold" ist eine Positions-Näherung anhand der ersten Bilder im HTML, kein echter Viewport-Test.

Und keine Gesamtpunktzahl. Ein „Performance-Score 62" suggeriert eine Präzision, die eine reine Byte-Analyse nicht hat — und lenkt von der eigentlichen Frage ab: welches Budget reißt zuerst, und was kostet der billigste Fix dagegen.

Für die Umsetzung der Befunde: Perf Budget Fix.

Hintergrund im Blog