Start · Sprachen · JavaScript · Referenz · Performance.measureUserAgentSpecificMemory()

Performance.measureUserAgentSpecificMemory()

Methode

Schätzt asynchron den Speicherverbrauch einer Webanwendung einschließlich ihrer Iframes und Worker und liefert eine Aufschlüsselung nach Herkunft und Typ.

seit JavaScript Experimentell: Chrome/Edge 89+ (nicht in Firefox u Kategorie: webapi

Signatur

Performance.prototype.measureUserAgentSpecificMemory()

Beschreibung

performance.measureUserAgentSpecificMemory() gibt ein Promise zurück. Es wird mit einer Schätzung des Speichers erfüllt, den der Browser für die aktuelle Seite belegt. Mitgezählt werden alle Iframes und Worker derselben Browsing-Context-Gruppe. Die ältere, nicht standardisierte Eigenschaft performance.memory meldete nur den JS-Heap des Hauptthreads. Diese Methode umfasst dagegen auch DOM-Speicher und Worker und schlüsselt das Ergebnis nach URL und Container auf.

Die Methode ist vor allem für die Speicherüberwachung im Produktivbetrieb gedacht. Typische Einsätze sind Speicherlecks erkennen, Rückschritte zwischen zwei Releases finden und A/B-Tests eines neuen Features auswerten. Die Werte werden über viele Nutzer gesammelt und statistisch ausgewertet. Für das Debugging in Echtzeit taugen sie nicht, denn der Browser misst häufig erst bei der nächsten Garbage Collection. Das Promise kann deshalb mehrere Sekunden brauchen, bis es erfüllt wird (in Chrome bis zu etwa 20 Sekunden).

Voraussetzung ist ein ursprungsübergreifend isolierter Kontext (self.crossOriginIsolated === true). Die Seite muss dafür mit den Headern Cross-Origin-Opener-Policy: same-origin und Cross-Origin-Embedder-Policy: require-corp (oder credentialless) ausgeliefert werden. Aufrufen lässt sich die Methode im Fenster sowie in Shared und Service Workern, außerdem nur in einem sicheren Kontext (HTTPS).

Das Ergebnisobjekt enthält bytes (Gesamtschätzung) und breakdown, ein Array von Einträgen mit bytes, types (z. B. "JavaScript", "DOM") und attribution. Jede attribution nennt die url, den scope (z. B. "Window", "DedicatedWorkerGlobalScope") und gegebenenfalls einen container mit id und src des einbettenden Iframes.

Rückgabewert

Typ
Promise<MemoryMeasurement>
Beschreibung

Ein Promise, das mit einem Objekt { bytes: number, breakdown: Array<{ bytes: number, attribution: Array<{ url: string, scope: string, container?: { id: string, src: string } }>, types: string[] }> } erfüllt wird. Ist der Kontext nicht ursprungsübergreifend isoliert, wird es mit einer SecurityError-DOMException abgelehnt.

Beispiele

Einmalige Messung mit Feature-Erkennung

const measureMemory = async () => {
  if (!('measureUserAgentSpecificMemory' in performance)) {
    console.warn('API wird von diesem Browser nicht unterstützt.');
    return;
  }
  if (!self.crossOriginIsolated) {
    console.warn('Seite ist nicht cross-origin-isoliert (COOP/COEP fehlen).');
    return;
  }
  try {
    const result = await performance.measureUserAgentSpecificMemory();
    console.log(`Gesamt: ${(result.bytes / 1024 / 1024).toFixed(1)} MiB`);
  } catch (err) {
    if (err.name === 'SecurityError') {
      console.error('Messung im aktuellen Kontext nicht erlaubt.');
    } else {
      throw err;
    }
  }
};

measureMemory();
Gesamt: 42.7 MiB

Aufschlüsselung nach Herkunft und Typ

const result = await performance.measureUserAgentSpecificMemory();

for (const entry of result.breakdown) {
  if (entry.bytes === 0) continue;
  const where = entry.attribution
    .map(({ url, scope, container }) =>
      `${scope} ${url}${container ? ` (iframe #${container.id})` : ''}`)
    .join(', ') || 'geteilt/unbekannt';
  console.log(`${entry.bytes} Bytes [${entry.types.join(', ')}] → ${where}`);
}
31457280 Bytes [JavaScript] → Window https://example.com/ 4194304 Bytes [DOM] → Window https://example.com/ 2097152 Bytes [JavaScript] → DedicatedWorkerGlobalScope https://example.com/worker.js

Monitoring mit zufälligem Intervall (Poisson-Verteilung)

// Zufällige Intervalle vermeiden systematische Verzerrungen
const MEAN_INTERVAL_MS = 5 * 60 * 1000; // im Mittel alle 5 Minuten

const nextInterval = () => -Math.log(Math.random()) * MEAN_INTERVAL_MS;

const scheduleMeasurement = () => {
  if (!self.crossOriginIsolated ||
      !performance.measureUserAgentSpecificMemory) return;

  setTimeout(async () => {
    try {
      const { bytes } = await performance.measureUserAgentSpecificMemory();
      navigator.sendBeacon('/analytics/memory', JSON.stringify({
        bytes,
        page: location.pathname,
        ts: Date.now()
      }));
    } catch (err) {
      console.error('Speichermessung fehlgeschlagen:', err);
    }
    scheduleMeasurement();
  }, nextInterval());
};

scheduleMeasurement();

// Wichtig · Fallstricke

  • Browser-Unterstützung: Die API ist experimentell und nur in Chromium-Browsern verfügbar (Chrome/Edge ab 89). Firefox und Safari unterstützen sie nicht. Prüfen Sie deshalb immer vorher, ob die Methode vorhanden ist.
  • Cross-Origin-Isolation ist Pflicht: Ohne die Header COOP same-origin und COEP require-corp/credentialless wird das Promise mit SecurityError abgelehnt. COEP kann Ressourcen von Drittanbietern blockieren (Bilder, Skripte, Iframes), wenn diese keine CORP- oder CORS-Header senden. Testen Sie das vor der Einführung gründlich.
  • Keine Echtzeit-Werte: Das Ergebnis kommt oft erst nach der nächsten Garbage Collection an und kann viele Sekunden verzögert sein. Rufen Sie die Methode nicht in Schleifen oder bei jeder Nutzeraktion auf.
  • Nur Schätzungen: Die Werte hängen von Browser, Version, Plattform und Anzahl der Prozesse ab. Vergleichen Sie Messwerte nur innerhalb derselben Umgebung und werten Sie sie statistisch aus, also über viele Messungen gemittelt.
  • Datenschutz: Speicher von ursprungsübergreifenden Iframes wird nicht einzeln aufgeschlüsselt, sondern nur dem einbettenden Container zugeordnet. So lassen sich keine Informationen über fremde Origins ableiten.
  • Die Methode ersetzt die nicht standardisierte Eigenschaft performance.memory, die veraltet ist.