Skripte verzögern, bis sie benötigt werden
Laden Sie JavaScript bei Bedarf mithilfe von IntersectionObserver und Benutzerinteraktions-Triggern

Skripte verzögern, bis sie benötigt werden
Laut dem [url=https:\/\/almanac.httparchive.org\/en\/2025\/page-weight]2025 Web Almanac[\/url] liefert die durchschnittliche mobile Seite 251 KB an ungenutztem JavaScript aus. Das ist JavaScript, das der Browser herunterlädt, analysiert und kompiliert, bevor ein Besucher es überhaupt benötigt. Formulare, auf die niemand geklickt hat. Chat-Widgets, die niemand geöffnet hat. Kartenintegrationen, die sich unter dem Falz (below the fold) befinden. All dies konkurriert während der kritischsten Phase des Seitenladens um Bandbreite und CPU-Zeit.
Der effektivste Weg, damit umzugehen, besteht darin, Skripte erst dann zu laden, wenn sie tatsächlich benötigt werden. Dies unterscheidet sich von der Verwendung des [url=\/pagespeed\/async-vs-defer-javascript-and-core-web-vitals]async- oder defer-Attributs[\/url] in einem Skript-Tag. Diese Attribute laden das Skript immer noch während des Seitenladens herunter; sie ändern lediglich den Zeitpunkt der Ausführung. Das Laden bei Bedarf (On-demand loading) lädt das Skript überhaupt nicht herunter, bis ein Trigger ausgelöst wird.
Zuletzt überprüft von [url=https:\/\/www.linkedin.com\/in\/arjenkarel\/]Arjen Karel[\/url] im März 2026
Bei Bildern machen wir das schon lange. Es nennt sich Lazy Loading. Beim Lazy Loading wird ein Bild unter dem Falz erst kurz vor dem Hineinscrollen in den Sichtbereich geladen. Der Browser kann seine Ressourcen für das Herunterladen, Analysieren und Zeichnen von Dingen aufwenden, die tatsächlich benötigt werden. Das gleiche Prinzip gilt für JavaScript. Es behebt die [url=\/pagespeed\/reduce-unused-javascript-lighthouse]Lighthouse-Warnung "Ungenutztes JavaScript reduzieren"[\/url] und verbessert Reaktionsmetriken wie [url=\/core-web-vitals\/interaction-to-next-paint]Interaction to Next Paint (INP)[\/url].
Leider ist es nicht so einfach wie das Hinzufügen von Um Skripte nach dem Seitenladen zur Seite hinzuzufügen, benötigen wir eine kleine Funktion, die ein Skript-Element erstellt und es an den Dokumentenkopf anhängt.
Der Parameter Nachdem die Hilfsfunktion zur Injektion bereitsteht, benötigen wir einen Trigger. Es gibt zwei zuverlässige Methoden: das Laden, wenn ein Element in den Sichtbereich scrollt, und das Laden, wenn der Benutzer mit einem Element interagiert.
Der IntersectionObserver wird ausgelöst, wenn ein Element in den Viewport eintritt. Dies ist der richtige Trigger für Skripte, die an einen bestimmten Abschnitt der Seite gebunden sind: einen Karten-Container, einen Kommentarbereich oder ein eingebettetes Widget unter dem Falz.
Die Funktion erwartet die Skript-URL, einen CSS-Selektor für das Element, das das Laden auslösen soll, und einen optionalen Callback zur Initialisierung. Wenn das Element in den Sichtbereich scrollt, wird das Skript injiziert und der Observer trennt die Verbindung.
IntersectionObserver wird in allen modernen Browsern unterstützt (95,76 % globale Abdeckung laut [url=https:\/\/caniuse.com\/intersectionobserver]Can I Use[\/url]). Ein Polyfill ist nicht erforderlich.
Die effektivste Methode besteht darin, ein Skript erst dann zu laden, wenn der Besucher tatsächlich mit dem Element interagiert, das es benötigt. Ein [url=\/pagespeed\/chat-widget-perfect-core-web-vitals]Chat-Widget[\/url] muss erst geladen werden, wenn jemand auf die Chat-Schaltfläche klickt. Eine Formularvalidierungs-Bibliothek muss erst geladen werden, wenn der Benutzer ein Formularfeld fokussiert.
Diese Funktion hört auf die angegebenen Ereignisse am Ziel-Element. Beim ersten Ereignis entfernt sie alle Listener und injiziert das Skript. Der Vorteil: Wenn der Besucher nie mit dem Element interagiert, wird das Skript überhaupt nicht geladen.
Dieses Muster funktioniert für jedes Skript, das während des ersten Seitenladens nicht benötigt wird. Einige häufige Anwendungsfälle:
Nicht jedes Skript sollte verzögert werden. Wenn ein Skript für das Rendern von Inhalten oberhalb des Falzes verantwortlich ist, wird das Verzögern Ihr [url=\/core-web-vitals\/largest-contentful-paint]Largest Contentful Paint (LCP)[\/url] verschlechtern, nicht verbessern. Skripte, die Ihre Header-Navigation initialisieren, Ihren Hero-Bereich rendern oder kritische A\/B-Testvarianten einrichten, müssen frühzeitig ausgeführt werden.
Die Regel ist einfach: Wenn der Besucher das, was das Skript erzeugt, innerhalb des ersten Viewports sieht oder damit interagiert, laden Sie es normal. Wenn das Skript etwas unterhalb des Falzes oder hinter einer Benutzeraktion steuert, verzögern Sie es mit einem der oben genannten Muster.
Tipp: Eine vollständige Übersicht über alle JavaScript-Ladestrategien finden Sie unter [url=\/pagespeed\/14-methods-to-defer-javascript]16 Methoden zum Verzögern oder Planen von JavaScript[\/url].
Der [url=https:\/\/almanac.httparchive.org\/en\/2025\/performance]2025 Web Almanac[\/url] berichtet von einer medianen mobilen Total Blocking Time von 1.916 ms, was einem Anstieg von 58 % gegenüber 2024 entspricht. Ein Großteil dieser Blockierung stammt von JavaScript, das während des Seitenladens nicht ausgeführt werden musste. Indem Sie nicht-kritische Skripte verzögern, entfernen Sie diese vollständig aus dem kritischen Pfad.
Überprüfen Sie nach der Implementierung des Ladens bei Bedarf die Verbesserung mit [url=https:\/\/coredash.app]Real User Monitoring[\/url]. Überprüfen Sie Ihre INP-Werte und die Total Blocking Time in den Felddaten, nicht nur in Lighthouse. Lab-Tests laufen auf schnellen Maschinen mit leeren Caches. Ihre Besucher nutzen mobile Netzwerke mit 15 geöffneten Browser-Tabs. Dort zeigt sich der Unterschied.
[include]cwv\/authorbio.html[\/include]
loading="lazy" zu einem Bild, aber mit einer kleinen Hilfsfunktion und einem Trigger können wir es umsetzen.
Der Hilfsskript zur Skript-Injektion
function injectScript(scriptUrl, callback) {
const script = document.createElement('script');
script.src = scriptUrl;
if (typeof callback === 'function') {
script.onload = callback;
}
document.head.appendChild(script);
}
scriptUrl ist die URL des zu ladenden Skripts. Die optionale callback-Funktion wird ausgeführt, nachdem das Skript geladen wurde. Dies ist wichtig für Skripte, die eine Initialisierung benötigen, wie z. B. das Aufrufen von initMap() nach dem Laden der Google Maps API.
Das Laden bei Bedarf auslösen
IntersectionObserver: laden, wenn sichtbar
function injectScriptOnIntersection(scriptUrl, elementSelector, callback) {
const element = document.querySelector(elementSelector);
const observer = new IntersectionObserver((entries, obs) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
injectScript(scriptUrl, callback);
obs.unobserve(entry.target);
}
});
});
observer.observe(element);
}
\/\/ Laden der Google Maps API, wenn der Karten-Container in den Sichtbereich scrollt
injectScriptOnIntersection(
'https:\/\/maps.googleapis.com\/maps\/api\/js?key=YOUR_KEY',
'#map-container',
() => initMap()
);
Bei Interaktion: laden, wenn der Benutzer interagiert
function injectScriptOnInteraction(scriptUrl, elementSelector, eventTypes, callback) {
const element = document.querySelector(elementSelector);
const handler = () => {
eventTypes.forEach(type => element.removeEventListener(type, handler));
injectScript(scriptUrl, callback);
};
eventTypes.forEach(type => {
element.addEventListener(type, handler);
});
}
\/\/ Chat-Widget-Skript laden, wenn die Chat-Schaltfläche angeklickt oder mit der Maus berührt wird
injectScriptOnInteraction(
'chat-widget.js',
'#chat-button',
['click', 'mouseover', 'touchstart'],
() => initChat()
);
Auswirkungen in der Praxis
Wann man nicht verzögern sollte
Die Verbesserung messen

