Drei kleine, unabhängige Funde aus einem einzigen Lighthouse-Audit — behoben an einem Nachmittag, ohne dass sich am Design auch nur ein Pixel verändert hat.

Ein routinemäßiger Lighthouse-Durchlauf auf der eigenen Seite hat drei unabhängige, kleine Funde zutage gefördert — keiner davon spektakulär für sich allein, aber in Summe ein Nachmittag, der sich gelohnt hat. Kein Redesign, keine neue Architektur: drei gezielte Fixes an drei völlig unterschiedlichen Stellen.

Auf den Punkt: Ein Menü-Button, der für Tastatur und Screenreader nicht sauber funktionierte. Eine CSS-Datei, die unminifiziert ausgeliefert wurde. Ein Logo, das dem Browser nicht mitteilte, dass es die wichtigste Ressource auf der Seite ist. Alle drei Funde kamen aus einem einzigen Lighthouse-Audit, alle drei Fixes waren in wenigen Zeilen Code erledigt.

Fund 1: Ein Button, der keiner war

Das Hamburger-Menü im Header war im Markup ein <div> mit aria-label="Menü öffnen" und aria-expanded="false" — sieht nach einem interaktiven Element aus, ist aber keins. Die axe-Prüfregeln aria-allowed-attr und aria-prohibited-attr markierten das zu Recht: bestimmte ARIA-Attribute dürfen nur auf Elementen mit passender nativer Rolle stehen, ein bloßes <div> bringt diese Rolle nicht mit.

Der Fix war ein Element-Tausch: <div> wurde zu einem echten <button>. Damit kommen Fokus-Reihenfolge, Tastaturbedienung (Enter/Leertaste) und die korrekte Rolle für Screenreader automatisch vom Browser — ohne eine einzige Zeile zusätzliches JavaScript. Der einzige Nebenaufwand: das Projekt fährt bewusst kein Tailwind-Preflight, also brauchte .hamburger ein paar manuelle Browser-Default-Resets (Hintergrund, Rahmen, Schriftart), damit der Button nicht plötzlich wie ein Standard-Button aussieht.

Fund 2: 100 KB CSS, die niemand angefordert hatte

public/css/main.css wurde bislang unverändert ausgeliefert — Kommentare, Einrückungen, alles inklusive. Lighthouse hatte hier rund 20% Einsparpotenzial angemerkt. Der Fix war ein neuer Build-Schritt (scripts/minify-public-css.mjs), der nach dem Astro-Build die CSS-Dateien im dist/-Output über esbuild minifiziert — eine Dependency, die über Vite ohnehin schon im Projekt steckt, kein neues Paket nötig. Die Quelldateien in public/css/ bleiben unangetastet und weiterhin von Hand editierbar.

Die realen Zahlen aus dem aktuellen Build:

100/100
PSI Barrierefreiheit
Mobile & Desktop
main.css 100,2 KB79,5 KB
v2.css 25,2 KB20,8 KB
webdesign.css 31,0 KB22,5 KB

Live nachgemessen aus dem aktuellen Produktions-Build. PSI-Werte: PageSpeed Insights, Desktop-Emulation, Live-Messung vom 12. September 2026 — Barrierefreiheit steht dort auf allen vier gemessenen Seiten (Mobile wie Desktop) konstant bei 100/100.

Fund 3: Das wichtigste Bild der Seite lud wie jedes andere

Lighthouse identifiziert auf jeder Seite ein Largest-Contentful-Paint-Element — bei uns durchgehend das Header-Logo. Die Diagnose "LCP request discovery" stand aber auf 0: Der Browser bekam keinen Hinweis, dass genau dieses Bild bevorzugt geladen werden sollte, und reihte es stattdessen neben Fonts und anderen Requests mit normaler Priorität ein.

Der Fix war ein einziges HTML-Attribut: fetchpriority="high" auf dem <img>-Tag des Header-Logos in Header.astro — bewusst nur dort, nicht am Footer-Logo, das im initialen Viewport ohnehin nie relevant ist.

Was das heute bedeutet — und was wir bewusst nicht angefasst haben

Eine aktuelle Live-Messung auf Desktop zeigt das Gesamtbild: Leistung, Barrierefreiheit, Best Practices und SEO stehen alle bei 100/100. Auf Mobile bleiben Barrierefreiheit, Best Practices und SEO ebenso stabil bei 100/100/100 — nur der reine Leistungs-Zeitwert schwankt zwischen zwei aufeinanderfolgenden Läufen spürbar (in unseren Messungen zwischen 68 und 87), weil die simulierte Drosselung auf gedrosseltem 4G störanfällig für die aktuelle Serverlast bei Google ist. Das ist kein Widerspruch zu den Fixes — es zeigt nur, dass regelbasierte Prüfungen (Barrierefreiheit, SEO) deterministisch sind, während Zeit-Messungen unter simulierter Last es nie ganz sind.

Nicht angefasst haben wir bewusst zwei andere Lighthouse-Hinweise: "unused JavaScript" (die React/Astro-Client-Runtime auf interaktiven Inseln) und "unused CSS" (ein gemeinsames main.css für alle Seiten). Beides sind bewusste Architekturentscheidungen und keine Bugs — client:load sorgt dafür, dass Navigation und Theme-Switch sofort interaktiv sind, und ein gemeinsames Stylesheet spart mehr Requests, als es an ungenutztem CSS kostet. Ein Audit ernst zu nehmen heißt nicht, jeden gelben Balken wegzuklicken — es heißt, die Funde zu verstehen und gezielt die zu beheben, die tatsächlich etwas kosten.

Kostenloser PageSpeed-Check

Wissen Sie, wo Ihre Website noch Potenzial liegen lässt?

Wir schauen uns Ihre Seite mit echten Lighthouse- und PSI-Daten an und zeigen, welche kleinen Fixes den größten Unterschied machen — nicht nur beim Design, auch technisch und bei der Barrierefreiheit.

Kostenlose Potenzialanalyse Preise & Konditionen

Kostenlos & unverbindlich · Direkt mit den Gründern · 30 Min.

FAQ

Warum war der Hamburger-Button ein Accessibility-Problem — er hat doch funktioniert? +

Er funktionierte für Maus-Klicks, aber nicht sauber für Tastatur- und Screenreader-Nutzung. Ein <div> mit aria-expanded und aria-label sieht für Screenreader zwar nach einem interaktiven Element aus, ist aber ohne zusätzlichen Aufwand nicht per Tab erreichbar und nicht per Enter/Leertaste auslösbar. Die axe-Regeln aria-allowed-attr und aria-prohibited-attr schlagen genau deshalb an: bestimmte ARIA-Attribute sind nur auf Elementen mit passender nativer Rolle erlaubt. Ein echtes <button>-Element bekommt Fokus, Tastaturbedienung und die richtige Rolle automatisch vom Browser — kostenlos, ohne eigenen JavaScript-Code dafür.

Bringt CSS-Minifizierung überhaupt etwas, wenn Vercel ohnehin komprimiert ausliefert? +

Ja, aus zwei Gründen. Erstens: Gzip/Brotli komprimieren zwar zusätzlich, aber eine kleinere Ausgangsdatei bleibt auch nach der Kompression kleiner — die Einsparung addiert sich, sie ersetzt sich nicht. Zweitens: Der Browser muss die CSS-Datei nach dem Herunterladen parsen, und dabei zählt die tatsächliche Zeichenzahl, nicht die komprimierte Übertragungsgröße. Bei main.css sind das 21% weniger Bytes, die geparst werden müssen, bevor die Seite überhaupt gerendert werden kann.

Was macht fetchpriority="high" beim Header-Logo konkret? +

Es ist ein Hinweis an den Browser, eine bestimmte Ressource bevorzugt zu laden, statt sie in der normalen Warteschlange neben Fonts, Scripts und anderen Bildern einzureihen. Lighthouse hatte das Header-Logo als Largest-Contentful-Paint-Element identifiziert, aber die Diagnose "LCP request discovery" stand auf 0 — der Browser wusste nicht früh genug, dass genau dieses Bild besonders wichtig ist. Der Hint kostet eine einzige HTML-Eigenschaft und ändert nichts am Aussehen.

Warum schwanken Mobile-Performance-Werte zwischen zwei Läufen so stark, aber Barrierefreiheit bleibt immer bei 100? +

Barrierefreiheit, Best Practices und SEO sind bei Lighthouse größtenteils statische, regelbasierte Prüfungen — entweder ist ein <button> ein <button>, oder es ist keiner. Die Leistungsbewertung dagegen simuliert ein gedrosseltes 4G-Netz auf einem Mittelklasse-Handy und misst echte Ladezeiten — und die hängen zusätzlich davon ab, wie ausgelastet die Messserver von Google gerade sind. Zwei Läufe im Abstand von wenigen Minuten können deshalb 20 Punkte auseinanderliegen, ohne dass sich an der Seite etwas verändert hat. Wer eine einzelne Mobile-Performance-Zahl als Beweis zitiert, zitiert oft nur den Serverlast-Zufall des Messzeitpunkts.

← Alle Blog-Artikel Der teuerste Main-Thread-Fresser: ein Farbverlauf →Wo diese Fixes bei Kundenprojekten ansetzen →