Back

Wann sollte Ihr Code ausgeführt werden: Page Load Events erklärt

Wann sollte Ihr Code ausgeführt werden: Page Load Events erklärt

Wann sollte Ihr JavaScript tatsächlich ausgeführt werden? Diese Frage stellt sich jedem Frontend-Entwickler, egal ob Sie das DOM in Vanilla JavaScript manipulieren oder Component Lifecycles in React verwalten. Die Antwort hängt davon ab, die Page Load Events des Browsers zu verstehen und den richtigen Hook für Ihre spezifischen Anforderungen zu wählen.

Wichtigste Erkenntnisse

  • DOMContentLoaded wird ausgelöst, wenn das HTML-Parsing abgeschlossen ist, während load auf alle Ressourcen wartet
  • Moderne Browser verwenden die Page Visibility und Lifecycle APIs anstelle unzuverlässiger unload-Events
  • React und andere Frameworks handhaben das Timing über Component Lifecycle Methods
  • Prüfen Sie document.readyState, um zu vermeiden, dass bereits ausgelöste Events verpasst werden

Den klassischen Browser-Lifecycle verstehen

Der Browser löst Events zu bestimmten Zeitpunkten während des Seitenladens aus. Zu wissen, wann jedes Event ausgelöst wird – und was zu diesem Zeitpunkt verfügbar ist – bestimmt, wo Ihr Code hingehört.

DOMContentLoaded vs. load: Der entscheidende Unterschied

DOMContentLoaded wird ausgelöst, wenn das HTML vollständig geparst und der DOM-Baum aufgebaut ist. Externe Ressourcen wie Bilder, Stylesheets und iframes werden noch geladen. Dies ist Ihre früheste Gelegenheit, DOM-Elemente sicher abzufragen und zu manipulieren:

document.addEventListener('DOMContentLoaded', () => {
    // DOM is ready, but images might still be loading
    const button = document.querySelector('#submit');
    button.addEventListener('click', handleSubmit);
});

Das load-Event wartet auf alles – Bilder, Stylesheets, iframes und andere externe Ressourcen. Verwenden Sie es, wenn Sie vollständige Ressourceninformationen benötigen:

window.addEventListener('load', () => {
    // All resources loaded - image dimensions are available
    const img = document.querySelector('#hero');
    console.log(`Image size: ${img.naturalWidth}x${img.naturalHeight}`);
});

Wie Scripts das Timing beeinflussen

Reguläre <script>-Tags blockieren DOMContentLoaded – der Browser muss sie ausführen, bevor er fortfährt. Scripts mit defer werden jedoch nach dem DOM-Parsing, aber vor dem Auslösen von DOMContentLoaded ausgeführt. Scripts mit async laden parallel und werden sofort nach dem Download ausgeführt, möglicherweise vor oder nach DOMContentLoaded.

Für elementspezifische Ressourcen verwenden Sie individuelle load-Events:

const img = new Image();
img.addEventListener('load', () => console.log('Image ready'));
img.src = 'photo.jpg';

Moderne Ansätze: document.readyState und darüber hinaus

Verwendung von document.readyState

Anstatt zu hoffen, dass Ihr Event Listener rechtzeitig angehängt wird, prüfen Sie den aktuellen Status:

function initialize() {
    // Your initialization code
}

if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initialize);
} else {
    // DOMContentLoaded already fired
    initialize();
}

Die drei Zustände sind:

  • 'loading' - Dokument wird geparst
  • 'interactive' - Parsing abgeschlossen, DOMContentLoaded wird gleich ausgelöst
  • 'complete' - Alle Ressourcen geladen

jQuerys $(document).ready() war im Wesentlichen ein browserübergreifender Wrapper für dieses Muster. Heute handhaben native APIs dies zuverlässig über alle Browser hinweg.

Page Visibility und Lifecycle API: Die neue Realität

Warum beforeunload und unload problematisch sind

Moderne Browser optimieren die Performance aggressiv durch Funktionen wie den Back-Forward-Cache (bfcache). Seiten, die in den bfcache gelangen, werden nicht entladen – sie werden suspendiert. Das bedeutet, beforeunload- und unload-Events werden nicht zuverlässig ausgelöst, wenn Benutzer wegnavigieren. Zusätzlich beschränken oder ignorieren Browser jetzt benutzerdefinierte Nachrichten in beforeunload-Dialogen, um Missbrauch zu verhindern.

Die Page Visibility API als Alternative

Anstelle unzuverlässiger unload-Events verwenden Sie die Page Visibility API, um zu reagieren, wenn Benutzer Tabs wechseln oder den Browser minimieren:

document.addEventListener('visibilitychange', () => {
    if (document.hidden) {
        // Page is hidden - pause expensive operations
        pauseVideoPlayback();
        throttleWebSocket();
    } else {
        // Page is visible again
        resumeOperations();
    }
});

Page Lifecycle States

Die Page Lifecycle API erweitert dies um Zustände wie frozen (Tab suspendiert, um Speicher zu sparen) und terminated:

document.addEventListener('freeze', () => {
    // Save state - tab might be discarded
    localStorage.setItem('appState', JSON.stringify(state));
});

document.addEventListener('resume', () => {
    // Restore after being frozen
    hydrateState();
});

React useEffect vs. DOMContentLoaded

In React und anderen modernen Frameworks verwenden Sie selten direkt DOMContentLoaded. Component Lifecycle Methods handhaben das Initialisierungs-Timing:

// React component
import { useEffect } from 'react';

function MyComponent() {
    useEffect(() => {
        // Runs after component mounts and DOM updates
        // Similar timing to DOMContentLoaded for this component
        initializeThirdPartyLibrary();
        
        return () => {
            // Cleanup on unmount
            cleanup();
        };
    }, []); // Empty dependency array = run once after mount
    
    return <div>Component content</div>;
}

Für Next.js oder andere SSR-Frameworks läuft Code in useEffect nur auf dem Client nach der Hydration – das Framework handhabt die Komplexität des Server- vs. Client-Ausführungs-Timings.

Den richtigen Hook wählen

Für Vanilla JavaScript:

  • DOM-Manipulation: Verwenden Sie DOMContentLoaded
  • Ressourcenabhängiger Code: Verwenden Sie das window load-Event
  • Zustandspersistierung: Verwenden Sie die Page Visibility API
  • Prüfung des aktuellen Zustands: Verwenden Sie document.readyState

Für SPAs und Frameworks:

  • Component-Initialisierung: Verwenden Sie Framework-Lifecycle (useEffect, mounted, etc.)
  • Routenänderungen: Verwenden Sie Router-Events
  • Hintergrund/Vordergrund: Verwenden Sie weiterhin die Page Visibility API

Vermeiden Sie diese Muster:

  • Verlassen Sie sich nicht auf beforeunload/unload für kritische Operationen
  • Verwenden Sie DOMContentLoaded nicht in React-Komponenten
  • Gehen Sie nicht davon aus, dass Scripts in einem frischen Seitenladevorgang laufen (berücksichtigen Sie bfcache)

Fazit

JavaScript Page Load Events haben sich über einfache DOMContentLoaded- und load-Handler hinaus entwickelt. Während diese klassischen Events für Vanilla JavaScript wesentlich bleiben, erfordert moderne Entwicklung das Verständnis von Page Visibility, Lifecycle APIs und framework-spezifischen Mustern. Wählen Sie Ihre Initialisierungsstrategie basierend darauf, welche Ressourcen Sie benötigen und ob Sie mit einer server-gerenderten Seite arbeiten oder eine vollständige SPA erstellen. Am wichtigsten ist: Verlassen Sie sich nicht auf veraltete Muster wie unload-Events – setzen Sie auf die modernen APIs, die für zeitgemäße Webanwendungen entwickelt wurden.

FAQs

Defer-Scripts werden in der Reihenfolge nach dem DOM-Parsing, aber vor DOMContentLoaded ausgeführt. Async-Scripts werden sofort nach dem Download ausgeführt und unterbrechen möglicherweise das Parsing. Verwenden Sie defer für Scripts, die DOM-Zugriff benötigen, und async für unabhängige Scripts wie Analytics.

Obwohl window.onload funktioniert, wird addEventListener bevorzugt, da es mehrere Handler ermöglicht und bestehende nicht überschreibt. Das load-Event selbst bleibt nützlich, wenn Sie alle Ressourcen vollständig geladen benötigen, bevor Code ausgeführt wird.

Verwenden Sie useEffect mit einem leeren Dependency-Array für clientseitige Initialisierung. Dies läuft nach Abschluss der Hydration. Für serverseitigen Code verwenden Sie framework-spezifische Methoden wie getServerSideProps oder getStaticProps anstelle von Browser-Events.

Moderne Browser cachen Seiten und lösen beforeunload möglicherweise nicht aus, wenn Benutzer wegnavigieren. Verwenden Sie stattdessen die Page Visibility API, um zu erkennen, wann Benutzer die Seite verlassen, und persistieren Sie kritische Daten kontinuierlich statt beim Beenden.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.

OpenReplay