Ursprungstest der AbrufLater API

Brendan Kenny
Brendan Kenny

Es ist üblich, dass Webseiten Daten (oder „Beacons“) zurück an ihren Server senden. Ein Beispiel hierfür sind Analysedaten aus der aktuellen Sitzung eines Nutzers. Für Entwickler bedeutet dies einen Balanceakt: die Reduzierung konstanter, möglicherweise redundanter Anfragen, ohne das Risiko verpasster Daten zu riskieren, wenn der Tab geschlossen wurde oder der Nutzer die Seite verlassen hat, bevor ein Beacon gesendet werden kann.

Traditionell haben Entwickler pagehide- und visibilitychange-Ereignisse verwendet, um die Seite beim Entladen abzufangen und dann navigator.sendBeacon() oder einen fetch() mit keepalive für das Beaconing von Daten zu verwenden. Beide Ereignisse haben jedoch schwierige Grenzfälle, die je nach Browser des Nutzers variieren. Manchmal treffen die Ereignisse überhaupt nicht ein – insbesondere auf Mobilgeräten.

fetchLater() ist ein Vorschlag, diese Komplexität durch einen einzigen API-Aufruf zu ersetzen. Sie funktioniert genau so, wie der Name schon sagt: Sie fordert den Browser an, sicherzustellen, dass irgendwann eine Anfrage gestellt wird, auch wenn die Seite geschlossen ist oder der Nutzer die Seite verlässt.

fetchLater() ist in Chrome für Tests mit echten Nutzern im Rahmen eines Ursprungstests ab Version 121 (veröffentlicht im Januar 2024) bis Chrome 126 (Juli 2024) verfügbar.

Mit der fetchLater() API

const fetchLaterResult = fetchLater(request, options);

fetchLater() verwendet zwei Argumente, die im Allgemeinen identisch mit denen von fetch() sind:

  • Den request, entweder eine String-URL oder eine Request-Instanz.
  • Ein optionales options-Objekt, das den options aus fetch() mit einem Zeitlimit namens activateAfter erweitert.

fetchLater() gibt ein FetchLaterResult zurück, das derzeit nur eine einzige schreibgeschützte Property activated enthält, die auf true gesetzt wird, wenn „später“ übergeben wurde und der Abruf erfolgt ist. Jede Antwort auf die fetchLater()-Anfrage wird verworfen.

request

Die einfachste Verwendung ist eine URL für sich:

fetchLater('/endpoint/');

Wie bei fetch() können für eine fetchLater()-Anfrage jedoch viele Optionen festgelegt werden, darunter benutzerdefinierte Header, das Verhalten von Anmeldedaten, ein POST-Text und ein AbortController-signal zum Abbrechen.

fetchLater('/endpoint/', {
  method: 'GET',
  cache: 'no-store',
  mode: 'same-origin',
  headers: {Authorization: 'SUPER_SECRET'},
});

options

Das Optionsobjekt erweitert die Optionen von fetch() um ein Zeitlimit (activateAfter), falls die Anfrage nach dem Zeitlimit oder beim Entladen der Seite ausgelöst werden soll, je nachdem, was zuerst eintritt.

So können Sie entscheiden, ob Sie Daten zum absolut letzten Zeitpunkt oder zu einem Zeitpunkt erhalten, an dem sie zeitnah abgerufen werden sollen.

Wenn Ihre Nutzer beispielsweise eine App haben, die normalerweise den ganzen Arbeitstag lang geöffnet ist, möchten Sie vielleicht ein Zeitlimit von einer Stunde einplanen, um detailliertere Analysen zu erhalten und gleichzeitig ein Beacon zu erhalten, wenn der Nutzer die App vor Ablauf der vollen Stunde verlassen hat. Für die nächste Analysestunde kann dann eine neue fetchLater() eingerichtet werden.

const hourInMilliseconds = 60 * 60 * 1000;
fetchLater('/endpoint/', {activateAfter: hourInMilliseconds});

Anwendungsbeispiel

Ein Problem bei der Messung der Core Web Vitals in diesem Feld ist, dass sich die Leistungsmesswerte ändern können, bis der Nutzer eine Seite tatsächlich verlässt. Beispielsweise können jederzeit größere Layoutverschiebungen auftreten oder die Reaktion der Seite auf eine Interaktion kann sogar noch länger dauern.

Sie sollten jedoch nicht riskieren, dass alle Leistungsdaten durch fehlerhaftes oder unvollständiges Beaconing beim Entfernen einer Seite verloren gehen. Es ist die perfekte Wahl für fetchLater().

In diesem Beispiel wird die Bibliothek „web-vitals.js“ verwendet, um die Messwerte zu überwachen, und fetchLater(), um die Ergebnisse an einen Analyseendpunkt zu melden:

import {onCLS, onINP, onLCP} from 'web-vitals';

const queue = new Set();
let fetchLaterController;
let fetchLaterResult;

function updateQueue(metricUpdate) {
  // If there was an already complete request for whatever
  // reason, clear out the queue of already-sent updates.
  if (fetchLaterResult?.activated) {
    queue.clear();
  }

  queue.add(metricUpdate);

  // JSON.stringify used here for simplicity and will likely include
  // more data than you need. Replace with a preferred serialization.
  const body = JSON.stringify([...queue]);

  // Abort any existing `fetchLater()` and schedule a new one with
  // the update included.
  fetchLaterController?.abort();
  fetchLaterController = new AbortController();
  fetchLaterResult = fetchLater('/analytics', {
    method: 'POST',
    body,
    signal: fetchLaterController.signal,
    activateAfter: 60 * 60 * 1000, // Timeout to ensure timeliness.
  });
}

onCLS(updateQueue);
onINP(updateQueue);
onLCP(updateQueue);

Jedes Mal, wenn eine Messwertaktualisierung eingeht, wird jede vorhandene geplante fetchLater() mit einem AbortController abgebrochen und eine neue fetchLater() mit dem Update erstellt.

fetchLater() jetzt verwenden

Wie bereits erwähnt, ist fetchLater() bis Chrome 126 in einem Ursprungstest verfügbar. Hintergrundinformationen zu Ursprungstests unter Erste Schritte mit Ursprungstests

Für lokale Tests kann fetchLater mit dem Flag für experimentelle Webplattformfunktionen unter chrome://flags/#enable-experimental-web-platform-features aktiviert werden. Er kann auch aktiviert werden, indem Chrome über die Befehlszeile mit --enable-experimental-web-platform-features oder dem gezielteren --enable-features=FetchLaterAPI-Flag ausgeführt wird.

Wenn du es auf einer öffentlichen Seite verwendest, musst du die Funktion „Detect“ verwenden. Prüfe dazu, ob das globale fetchLater definiert ist, bevor du es verwendest:

if (globalThis.fetchLater) {
  // Set up beaconing using fetchLater().
  // ...
}

Feedback

Entwicklerfeedback ist wichtig, um die neuen Web-APIs richtig einzurichten. Daher sollten Sie Probleme und Feedback bei GitHub melden.

Weitere Informationen