Signatur
Beschreibung
Die schreibgeschützte Eigenschaft domContentLoadedEventEnd des Interfaces PerformanceNavigationTiming gibt einen DOMHighResTimeStamp in Millisekunden zurück. Er markiert den Moment, in dem alle Handler für das Ereignis DOMContentLoaded des aktuellen Dokuments fertig ausgeführt sind. Gemessen wird relativ zu startTime des Navigationseintrags, der bei Navigationen immer 0 ist, also ab dem Beginn der Navigation.
Zusammen mit domContentLoadedEventStart kannst du ausrechnen, wie lange deine eigenen DOMContentLoaded-Handler brauchen. Sind es viele oder rechenintensive Handler, siehst du das hier direkt. Die Differenz domContentLoadedEventEnd - startTime ist die bekannte Kennzahl „DOMContentLoaded-Zeit“, die auch die Browser-DevTools anzeigen.
Den Eintrag holst du normalerweise mit performance.getEntriesByType("navigation")[0]. Alternativ nutzt du einen PerformanceObserver mit type: "navigation" und buffered: true. Solange das Ereignis noch nicht fertig verarbeitet ist, hat die Eigenschaft den Wert 0.
Rückgabewert
DOMContentLoaded-Handler fertig sind. Ist 0, solange das Ereignis noch nicht vollständig verarbeitet wurde.Beispiele
DOMContentLoaded-Zeit und Handler-Dauer messen
window.addEventListener('load', () => {
const [nav] = performance.getEntriesByType('navigation');
if (!nav) return;
const dclZeit = nav.domContentLoadedEventEnd - nav.startTime;
const handlerDauer = nav.domContentLoadedEventEnd - nav.domContentLoadedEventStart;
console.log(`DOMContentLoaded nach ${dclZeit.toFixed(1)} ms`);
console.log(`Handler-Dauer: ${handlerDauer.toFixed(1)} ms`);
});
Zuverlässig per PerformanceObserver auslesen
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.domContentLoadedEventEnd > 0) {
console.log('DCL-Ende:', Math.round(entry.domContentLoadedEventEnd), 'ms');
observer.disconnect();
}
}
});
// buffered: true liefert auch Einträge, die schon vor dem Beobachten entstanden sind
observer.observe({ type: 'navigation', buffered: true });
Messwert an einen Analytics-Endpunkt senden
const reportDcl = () => {
const [nav] = performance.getEntriesByType('navigation');
if (!nav || nav.domContentLoadedEventEnd === 0) return;
const payload = JSON.stringify({
page: location.pathname,
dcl: Math.round(nav.domContentLoadedEventEnd),
type: nav.type // 'navigate', 'reload', 'back_forward' ...
});
navigator.sendBeacon('/analytics/timing', payload);
};
// Nach dem load-Ereignis ist der Wert sicher gesetzt
window.addEventListener('load', () => setTimeout(reportDcl, 0));
// Wichtig · Fallstricke
- Wert 0: Liest du die Eigenschaft innerhalb eines
DOMContentLoaded-Handlers oder davor aus, erhältst du0, weil das Ereignis noch nicht zu Ende verarbeitet ist. Lies sie erst nachloadaus oder verwende einenPerformanceObserver. - Keine Unix-Zeit: Der Wert bezieht sich auf
performance.timeOriginund nicht aufDate.now(). Absolute Zeit bekommst du mitperformance.timeOrigin + wert. - Genauigkeit: Zum Schutz vor Timing-Angriffen runden Browser die Werte oder versehen sie mit Rauschen. Firefox tut das zum Beispiel, wenn
privacy.reduceTimerPrecisionaktiv ist. Einzelwerte können also leicht abweichen. - bfcache: Wird eine Seite aus dem Back-Forward-Cache wiederhergestellt, entsteht kein neuer Navigationseintrag. Der Wert gehört dann weiterhin zum ursprünglichen Laden.
- Veraltet: Das ältere
performance.timing.domContentLoadedEventEnd(Navigation Timing Level 1) ist veraltet und liefert absolute Epoch-Zeitstempel. Nimm stattdessen diese Eigenschaft. - Kompatibilität: Alle modernen Browser unterstützen die Eigenschaft (Safari ab Version 15). Internet Explorer unterstützt sie nicht.