Signatur
Beschreibung
toJSON() ist die Serialisierungsmethode von PerformancePaintTiming. Sie erzeugt ein einfaches JavaScript-Objekt, das die öffentlichen Eigenschaften des Paint-Eintrags enthält. Das sind vor allem name ("first-paint" oder "first-contentful-paint"), entryType (immer "paint"), startTime und duration (bei Paint-Einträgen immer 0).
Gebraucht wird die Methode vor allem beim Real User Monitoring (RUM): Paint-Zeitpunkte wie First Contentful Paint (FCP) werden im Browser erfasst und als JSON an einen Analyse-Endpunkt geschickt. JSON.stringify() ruft toJSON() automatisch auf. Ohne diese Methode würde ein Performance-Eintrag nur zu {} serialisiert, weil seine Eigenschaften als Getter auf dem Prototyp liegen und keine eigenen Eigenschaften der Instanz sind.
Das zurückgegebene Objekt ist eine Momentaufnahme. Es hat keine Verbindung mehr zum ursprünglichen Eintrag und kann beliebig verändert oder erweitert werden, z. B. um die URL oder den Gerätetyp.
Rückgabewert
name, entryType, startTime und duration. In neueren Browsern kommen zusätzlich paintTime und presentationTime hinzu (aus dem PaintTimingMixin). Zurückgegeben wird ein Objekt, kein JSON-String.Beispiele
Paint-Einträge per PerformanceObserver serialisieren
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// toJSON() liefert ein einfaches Objekt
console.log(entry.toJSON());
}
});
// buffered: true liefert auch Einträge, die schon vor dem Registrieren entstanden sind
observer.observe({ type: 'paint', buffered: true });
First Contentful Paint an einen Analyse-Server senden
const sendFcp = (entry) => {
const payload = {
...entry.toJSON(),
page: location.pathname,
timestamp: Date.now(),
};
// sendBeacon funktioniert auch noch beim Verlassen der Seite
navigator.sendBeacon('/analytics/paint', JSON.stringify(payload));
};
new PerformanceObserver((list, obs) => {
const fcp = list.getEntriesByName('first-contentful-paint')[0];
if (fcp) {
sendFcp(fcp);
obs.disconnect();
}
}).observe({ type: 'paint', buffered: true });
Unterschied zwischen JSON.stringify mit und ohne toJSON
const [entry] = performance.getEntriesByType('paint');
if (entry) {
// JSON.stringify ruft toJSON() automatisch auf
console.log(JSON.stringify(entry));
// Getter liegen auf dem Prototyp, deshalb gibt es keine eigenen Schlüssel
console.log(Object.keys(entry));
// Das toJSON()-Ergebnis hat echte eigene Eigenschaften
console.log(Object.keys(entry.toJSON()));
}
// Wichtig · Fallstricke
- Kein String:
toJSON()gibt ein Objekt zurück. Einen JSON-String erhält man erst mitJSON.stringify(entry)oderJSON.stringify(entry.toJSON()). - Spread und
Object.assign()funktionieren nicht direkt:{ ...entry }ergibt ein leeres Objekt, weil die Eigenschaften Getter auf dem Prototyp sind. Deshalb immer{ ...entry.toJSON() }verwenden. - Browser-Kompatibilität: Firefox und Safari melden nur
first-contentful-paint,first-paintgibt es dort nicht. Die neueren FelderpaintTimeundpresentationTimesind noch nicht überall vorhanden. Der Code sollte also nicht auf bestimmte Schlüssel angewiesen sein. - Hintergrund-Tabs: Wird eine Seite im Hintergrund geladen, entstehen unter Umständen gar keine Paint-Einträge. Dann wird
toJSON()nie aufgerufen. - Zeitbasis:
startTimeist relativ zuperformance.timeOriginund keine Unix-Zeit. Für absolute Zeitpunkte muss manperformance.timeOrigin + startTimerechnen.