Signatur
Beschreibung
performance.mark() gehört zur User Timing API. Damit setzt du eigene, benannte Zeitmarken in die Performance-Timeline, zum Beispiel „Daten geladen“ oder „Rendering fertig“. Jede Marke ist ein PerformanceMark-Eintrag mit dem entryType "mark". Ihr startTime ist ein hochauflösender Zeitstempel in Millisekunden relativ zu performance.timeOrigin, und ihre duration ist immer 0.
Meist setzt man Marken paarweise und misst dann mit performance.measure() die Dauer zwischen ihnen. Die Einträge erscheinen außerdem im Performance-Panel der Browser-Entwicklertools. Mit performance.getEntriesByName(), getEntriesByType("mark") oder einem PerformanceObserver kannst du sie wieder auslesen.
Seit User Timing Level 3 gibt die Methode das erzeugte PerformanceMark-Objekt zurück. Über markOptions kannst du einen eigenen Zeitstempel (startTime) und beliebige Zusatzdaten (detail) mitgeben. So lassen sich Marken mit Kontext versehen, etwa mit einer Komponenten-ID oder einer Request-URL.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $markName Pflicht | string | Name der Marke. Er darf mehrfach vergeben werden, dann entstehen mehrere Einträge. Namen von PerformanceTiming-Attributen wie "navigationStart" sind verboten und lösen einen SyntaxError aus. |
|
| $markOptions | object | {} | Optionale Einstellungen:
|
Rückgabewert
PerformanceMark-Eintrag mit name, entryType ("mark"), startTime, duration (0) und detail. Ältere Browser (vor Level 3) geben undefined zurück.Beispiele
Dauer eines Fetch-Aufrufs messen
const loadUsers = async () => {
performance.mark('users:start');
const res = await fetch('https://jsonplaceholder.typicode.com/users');
const users = await res.json();
performance.mark('users:end');
const m = performance.measure('users:load', 'users:start', 'users:end');
console.log(`${users.length} Nutzer in ${m.duration.toFixed(1)} ms geladen`);
};
loadUsers();
Marke mit Zusatzdaten (detail) anlegen
const mark = performance.mark('component:rendered', {
detail: { component: 'Warenkorb', items: 3 }
});
console.log(mark.entryType, mark.duration);
console.log(mark.detail.component, mark.detail.items);
console.log(typeof mark.startTime);
Marken per PerformanceObserver beobachten
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.log(`Marke "${entry.name}" bei ${entry.startTime.toFixed(0)} ms`);
}
});
observer.observe({ type: 'mark', buffered: true });
performance.mark('app:init');
setTimeout(() => performance.mark('app:ready'), 200);
Eigenen Zeitstempel setzen und Marken aufräumen
const t0 = performance.now();
// ... aufwendige Berechnung ...
const sum = Array.from({ length: 1e6 }, (_, i) => i).reduce((a, b) => a + b, 0);
// Marke nachträglich mit früherem Zeitstempel eintragen
performance.mark('calc:start', { startTime: t0 });
performance.mark('calc:end');
const { duration } = performance.measure('calc', 'calc:start', 'calc:end');
console.log(sum, duration > 0);
// Einträge entfernen, um den Puffer klein zu halten
performance.clearMarks('calc:start');
performance.clearMarks('calc:end');
performance.clearMeasures('calc');
console.log(performance.getEntriesByName('calc:start').length);
// Wichtig · Fallstricke
- Speicher: Marken bleiben erhalten, bis
performance.clearMarks()aufgerufen wird. Wer in Schleifen oder langlebigen Single-Page-Apps viele Marken setzt, sollte sie regelmäßig löschen. - Verbotene Namen: Namen von
PerformanceTiming-Attributen (z. B."loadEventEnd","domComplete") lösen im Fenster-Kontext einenSyntaxErroraus. - Genauigkeit: Zum Schutz vor Timing-Angriffen (Spectre) runden Browser die Zeitstempel ab, meist auf 5–100 µs. Ohne Cross-Origin-Isolation ist die Auflösung gröber. Firefox mit
privacy.resistFingerprintingrundet noch stärker. - Kompatibilität: Die Methode selbst funktioniert in allen modernen Browsern und in Web Workern.
markOptionsund das zurückgegebene Objekt gibt es erst ab Chrome 78, Firefox 101 und Safari 14.1. Ältere Browser ignorieren die Optionen und gebenundefinedzurück. detailwird per structured clone kopiert. Funktionen oder DOM-Knoten lösen dort einenDataCloneErroraus.- In Node.js stehen die Funktionen global zur Verfügung (ab Version 16) oder über
require('node:perf_hooks').performance.