Signatur
Beschreibung
Die Eigenschaft domInteractive der Schnittstelle PerformanceNavigationTiming gibt einen DOMHighResTimeStamp in Millisekunden zurück. Er markiert den Zeitpunkt, an dem der HTML-Parser das Dokument fertig geparst hat und der Browser document.readyState gleich danach auf "interactive" setzt. Der Wert ist relativ zu startTime des Navigationseintrags, also dem Beginn der Navigation (bei Navigationseinträgen in der Regel 0).
Zu diesem Zeitpunkt steht der DOM-Baum vollständig zur Verfügung. Mit defer markierte Skripte wurden aber noch nicht ausgeführt, und Bilder, Stylesheets und iframes laden eventuell noch. Deshalb liegt domInteractive immer vor domContentLoadedEventStart und loadEventStart.
Der Messwert eignet sich, um die Parse-Dauer des HTML-Dokuments zu bestimmen, etwa domInteractive - responseEnd. Er zeigt auch, wie stark blockierende Skripte und Stylesheets im <head> den Parser bremsen. Den Wert erhält man über performance.getEntriesByType("navigation") oder über einen PerformanceObserver mit dem Typ "navigation".
Rückgabewert
readyState auf "interactive" wechselt. Solange dieser Zeitpunkt noch nicht erreicht ist, ist der Wert 0.Beispiele
domInteractive auslesen
const [nav] = performance.getEntriesByType("navigation");
if (nav) {
console.log(`DOM interaktiv nach ${nav.domInteractive.toFixed(1)} ms`);
}
Parse-Dauer und Zeitabstände zu späteren Phasen berechnen
window.addEventListener("load", () => {
// Kurz warten, damit loadEventEnd gesetzt ist
setTimeout(() => {
const [nav] = performance.getEntriesByType("navigation");
const metrics = {
htmlParsen: nav.domInteractive - nav.responseEnd,
bisDOMContentLoaded: nav.domContentLoadedEventStart - nav.domInteractive,
bisLoad: nav.loadEventStart - nav.domInteractive
};
console.table(metrics);
}, 0);
});
Mit PerformanceObserver erfassen und an Analytics senden
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
const payload = JSON.stringify({
url: entry.name,
domInteractive: Math.round(entry.domInteractive)
});
navigator.sendBeacon("/analytics/timing", payload);
}
});
// buffered: true liefert auch den bereits erzeugten Navigationseintrag
observer.observe({ type: "navigation", buffered: true });
// Wichtig · Fallstricke
- Wert 0: Wird die Eigenschaft zu früh gelesen, etwa in einem blockierenden Skript im
<head>, ist der Wert noch0. Erst nachDOMContentLoadedoderloadauslesen oder einenPerformanceObservermitbuffered: trueverwenden. - Nicht mit „Time to Interactive“ verwechseln:
domInteractivebedeutet nicht, dass die Seite für Nutzer bedienbar ist. Dafür eignen sich eher Kennzahlen wie INP oder Long Tasks. - Cross-Origin-Weiterleitungen: Gab es während der Navigation Weiterleitungen über fremde Ursprünge, können einzelne Zeitwerte des Eintrags ungenau sein oder auf
0stehen. - Genauigkeit: Aus Datenschutzgründen (Schutz vor Fingerprinting und Spectre) runden Browser die Zeitstempel. Firefox rundet ohne Cross-Origin-Isolation zum Beispiel auf 1 ms oder gröber.
- Veraltete Alternative:
performance.timing.domInteractiveaus Navigation Timing Level 1 ist veraltet und liefert absolute Epoch-Zeitstempel. Verwende stattdessenPerformanceNavigationTiming. - Bei Wiederherstellung aus dem Back/Forward-Cache (bfcache) entsteht kein neuer Navigationseintrag.