Zwei HTML-Attribute – async und defer – entscheiden darüber, ob dein JavaScript die Core Web Vitals verbessert oder zerstört. Hier erfährst du den genauen Unterschied, wann du welches Attribut verwendest und welche Fehler du unbedingt vermeiden solltest.
async: Download parallel, Ausführung sobald geladen (unterbricht Parsing)defer: Download parallel, Ausführung nach HTML-Parsing (DOM-Reihenfolge bleibt)defer – nur für unabhängige Analytics-Scripts asyncWenn du ein <script src="...">-Tag ohne weitere Attribute in deinen <head> setzt, stoppt der Browser das gesamte HTML-Parsing. Er lädt die JavaScript-Datei herunter, führt sie aus – und erst dann geht es mit dem Rest des HTML weiter. Das nennt sich render-blocking.
Das hat direkte Auswirkungen auf zwei Metriken, die Google seit 2021 als Ranking-Faktor bewertet:
Google's Core Web Vitals sind inzwischen ein etablierter Ranking-Faktor. Seiten mit gutem LCP (< 2,5 s) ranken messbar besser als Seiten mit schlechtem LCP (> 4,0 s). Und render-blockende Scripts sind eine der häufigsten Ursachen für schlechten LCP.
Schauen wir uns die drei Szenarien Schritt für Schritt an.
<!-- ⛔ Render-blocking: HTML-Parsing wird gestoppt -->
<script src="mein-script.js"></script>
Ablauf im Browser:
<script>-Tagmein-script.js herunterProblem: Auf einer langsamen Mobilverbindung kann das Script 2-3 Sekunden brauchen. In dieser Zeit sieht der Nutzer eine weiße Seite. LCP liegt dann jenseits von 4 Sekunden → rotes Feld bei Google PageSpeed Insights.
<!-- ✅ Für unabhängige Scripts: Analytics, A/B-Testing -->
<script async src="analytics.js"></script>
Ablauf:
Wichtig: Die Ausführungsreihenfolge bei async ist nicht garantiert. Wenn du drei async-Scripts hast, können sie in beliebiger Reihenfolge ausgeführt werden – das erste, das fertig geladen ist, wird als erstes ausgeführt. Das macht async ungeeignet für Scripts, die voneinander abhängen.
<!-- ✅ Für die meisten Scripts: DOM-abhängige Bibliotheken, UI-Scripts -->
<script defer src="app.js"></script>
Ablauf:
defer ist die sichere Wahl für fast alle Scripts, weil:
| Attribut | Download | Parsing pausiert? | Ausführungszeitpunkt | Reihenfolge garantiert? |
|---|---|---|---|---|
— (keins) |
Blockierend | ✗ Ja, sofort | Sofort beim Download | ✓ Ja |
async |
Parallel | ✗ Kurz bei Ausführung | Sobald geladen | ✗ Nein |
defer |
Parallel | ✓ Nie | Nach HTML-Parsing | ✓ Ja |
Diese Entscheidungshilfe deckt 95 % der Praxisfälle ab:
src): async und defer haben keine Wirkung auf Inline-ScriptsGooglebot rendert Seiten in zwei Wellen: Zuerst crawlt er das rohe HTML (fast immer), dann kommt das JavaScript-Rendering in einer zweiten Welle – manchmal mit Verzögerung von Stunden bis Tagen.
Was bedeutet das für async und defer?
Wenn dein kritischer Inhalt (H1, Produktbeschreibung, Preise) von JavaScript abhängt, solltest du auf JavaScript SEO für SPAs und Server-Side Rendering setzen. Für UI-Scripts (Animationen, Slider) ist JavaScript-Rendering kein Problem – Google sieht den Content trotzdem.
Du hast vielleicht schon den alten Rat gehört: "Packe alle Scripts ans Ende des <body>". Dieser Rat ist nicht falsch, aber in 2026 ist defer im <head> die bessere Praxis:
<!-- ✅ Empfohlen: defer im head -->
<head>
<script defer src="jquery.js"></script>
<script defer src="app.js"></script>
</head>
<!-- ⚠️ Veraltet, aber funktioniert noch: am Body-Ende -->
<body>
...Seiten-Inhalt...
<script src="jquery.js"></script>
<script src="app.js"></script>
</body>
<!-- ⛔ FALSCH: jQuery async + abhängiges Plugin -->
<script async src="jquery.js"></script>
<script async src="slider.js"></script> <!-- schlägt fehl wenn jQuery nicht fertig! -->
<!-- ✅ RICHTIG: Beide defer -->
<script defer src="jquery.js"></script>
<script defer src="slider.js"></script> <!-- wird nach jquery.js ausgeführt -->
Mit async könnte slider.js vor jquery.js ausgeführt werden – und dann fehlt jQuery noch. Das führt zu einem $ is not defined-Fehler. Mit defer läuft alles in der richtigen Reihenfolge.
<!-- ⚠️ Vorsicht: GTM mit defer kann Tracking-Probleme verursachen -->
<script defer src="gtm.js"></script>
<!-- ✅ Besser: GTM async (wie von Google empfohlen) -->
<script async src="https://www.googletagmanager.com/gtm.js?id=GTM-XXXXX"></script>
GTM und Google Analytics sind darauf ausgelegt, mit async geladen zu werden. Sie initialisieren sich selbst und haben keine Abhängigkeiten. defer würde hier dazu führen, dass Tracking-Events verpasst werden, die sehr früh im Seitenaufruf ausgelöst werden.
<!-- ⛔ Wirkungslos: async/defer auf Inline-Script -->
<script async>
console.log("Dieser Script ist trotzdem synchron!");
</script>
Das async-Attribut hat keine Wirkung auf Inline-Scripts (Scripts ohne src-Attribut). Inline-Scripts werden immer synchron ausgeführt, wenn der HTML-Parser auf sie trifft. Wenn du einen Inline-Script asynchron ausführen willst, verwende setTimeout oder lade den Code als externe Datei.
<!-- ✅ ES-Module: implizites defer -->
<script type="module" src="app.mjs"></script>
<!-- Entspricht: -->
<script defer src="app.mjs"></script>
Scripts mit type="module" werden automatisch mit defer-Verhalten geladen – das ist Teil der ES-Modul-Spezifikation. Du musst hier defer nicht explizit setzen.
Um render-blockende Scripts auf deiner Website zu finden, hast du mehrere Möglichkeiten:
lighthouse https://beispiel.de --view für detaillierte Performance-AnalyseSo sieht ein typischer, unoptimierter <head> aus:
<!-- ⛔ Vorher: 3 render-blockende Scripts -->
<head>
<script src="jquery-3.6.0.min.js"></script>
<script src="bootstrap.min.js"></script>
<script src="google-analytics.js"></script>
<script src="app.js"></script>
</head>
Und so sieht die optimierte Version aus:
<!-- ✅ Nachher: kein Script blockiert mehr -->
<head>
<!-- Analytics: unabhängig, async -->
<script async src="google-analytics.js"></script>
<!-- jQuery + Bootstrap + App: abhängig, defer -->
<script defer src="jquery-3.6.0.min.js"></script>
<script defer src="bootstrap.min.js"></script>
<script defer src="app.js"></script>
</head>
Das Ergebnis: HTML-Parsing läuft durch, LCP kann früh eintreten, alle Abhängigkeiten bleiben korrekt (jQuery vor Bootstrap vor App).
In WordPress registrierst und enqueust du Scripts über wp_enqueue_script(). Standardmäßig werden Scripts am Body-Ende geladen, aber du kannst das Verhalten mit Filtern anpassen:
// In functions.php: defer für alle eigenen Scripts
add_filter('script_loader_tag', function($tag, $handle, $src) {
// Nur für eigene Scripts (nicht Drittanbieter)
$own_scripts = ['my-theme-script', 'my-plugin-script'];
if (in_array($handle, $own_scripts)) {
return str_replace('>', ' defer>', $tag);
}
return $tag;
}, 10, 3);
Plugins wie "Autoptimize" oder "WP Rocket" bieten ebenfalls GUI-Optionen, um Scripts auf async oder defer umzustellen – ohne Code-Änderungen.
<head> haben entweder async oder deferdefer (nicht async)asyncdefer im <head> umgestelltdocument.write()-Aufrufe in externen ScriptsDas richtige Ladeattribut für deine JavaScript-Dateien ist eine der effektivsten Maßnahmen für schnellere Core Web Vitals und besseres SEO-Ranking – und es kostet nur wenige Sekunden Implementierungsaufwand. Die Faustregel lautet:
Kombiniere das mit dem Entfernen blockierender CSS-Ressourcen und du hast die Performance-Grundlagen deiner Website auf einem soliden Stand – was sich direkt in besseren Core Web Vitals und langfristig in besseren Rankings niederschlägt.