CSS & JavaScript
Rendern und Reagieren
CSS und JavaScript entscheiden, wie schnell eine Seite interaktiv wird. Beide können den Browser blockieren – CSS beim Rendern, JavaScript beim Reagieren.
CSS blockiert das Rendern
Der Browser rendert nichts, bis das CSS im <head> geladen ist. Deshalb:
- Kritisches CSS für den sichtbaren Bereich inline oder klein halten.
- Ungenutztes CSS entfernen – große Framework-Bündel wiegen schwer.
- Nicht-kritisches CSS verzögert nachladen, statt alles blockierend zu verlinken.
JavaScript nicht das Rendern blockieren lassen
Ein <script> ohne Attribut hält den Parser an. Zwei Auswege:
| Attribut | Verhalten |
|---|---|
defer | lädt parallel, führt nach dem HTML-Parsing in Reihenfolge aus |
async | lädt parallel, führt aus, sobald es da ist (Reihenfolge egal) |
Für die meisten App-Skripte ist defer die richtige Wahl. async passt für unabhängige Dinge wie Analytics.
<script src="/app.js" defer></script>
Weniger und kleineres JavaScript
Jedes Kilobyte JS muss geladen, geparst und ausgeführt werden – gerade auf schwachen Mobilgeräten teuer.
- Code-Splitting: nur laden, was die aktuelle Seite braucht.
- Tree-Shaking: toten Code beim Build entfernen.
- Dynamische Importe: schwere Komponenten (Charts, Editoren) erst bei Bedarf.
- Third-Party im Griff: jedes Fremd-Skript kostet – kritisch prüfen, was wirklich rein muss.
Long Tasks blockieren INP
Lange, ununterbrochene JS-Aufgaben (> 50 ms) blockieren den Main-Thread – Klicks reagieren träge. Gegenmittel:
- große Aufgaben aufteilen (yielding,
requestIdleCallback) - schwere Berechnungen in einen Web Worker auslagern
- Arbeit im Event-Handler minimieren, teure Teile aufschieben
Serverseitig rendern
HTML, das schon fertig vom Server kommt (SSR/SSG), ist schneller sichtbar als eine leere Seite, die erst per JavaScript aufgebaut wird. Frameworks wie Next.js liefern das ab Werk.
Kurz: CSS klein und kritisch halten, JS
deferred und gesplittet laden, Long Tasks zerlegen. Das zahlt direkt auf LCP und INP ein.