Verbessertes Schließen von Seiten im synchronen XMLHttpRequest()

Verzögerte Navigation reduzieren

Joe Medley
Joe Medley

Es ist nicht ungewöhnlich, dass eine Seite oder App nicht eingereichte Analysedaten oder andere Daten enthält, wenn der Nutzer sie schließt. Zur Vermeidung von Datenverlusten verwenden einige Websites einen synchronen Aufruf von XMLHttpRequest(), um die Seite oder App geöffnet zu lassen, bis ihre Daten an den Server übergeben werden. Es gibt nicht nur bessere Möglichkeiten, Daten zu speichern, auch diese Technik beeinträchtigt die Nutzererfahrung, da das Schließen der Seite um einige Sekunden verzögert wird.

Diese Vorgehensweise muss geändert werden und die Browser reagieren darauf. Die Spezifikation XMLHttpRequest() ist bereits eingestellt und entfernt. Der erste Schritt macht Chrome 80. Synchrone Aufrufe in mehreren Event-Handlern, insbesondere beforeunload, unload, pagehide und visibilitychange, werden nicht zugelassen, wenn sie bei der Ablehnung ausgelöst werden. WebKit hat vor Kurzem auch einen Commit erhalten, der dieselbe Verhaltensänderung implementiert.

In diesem Artikel werden Optionen für Nutzer beschrieben, die Zeit zum Aktualisieren ihrer Websites benötigen. Außerdem erläutere ich Alternativen zu XMLHttpRequest().

Vorübergehend deaktivierte Funktionen

Chrome möchte nicht einfach nur den Stecker für XMLHttpRequest() ziehen. Daher gibt es einige vorübergehende Deaktivierungsoptionen. Für Websites im Internet ist ein Ursprungstest verfügbar. Damit fügen Sie den Kopfzeilen der Seite ein ursprungsspezifisches Token hinzu, das synchrone XMLHttpRequest()-Aufrufe ermöglicht. Diese Option endet kurz vor der Auslieferung von Chrome 89 im März 2021. Enterprise Chrome-Kunden können auch das Richtlinien-Flag AllowSyncXHRInPageDismissal verwenden, das zur gleichen Zeit endet.

Alternativen

Unabhängig davon, wie Sie Daten an den Server zurücksenden, sollten Sie nicht mit dem Entladen der Seite warten, um alle Daten auf einmal zu senden. Abgesehen von einer schlechten Nutzererfahrung ist das Unload in modernen Browsern unzuverlässig und riskiert einen Datenverlust, wenn etwas schiefgeht. Insbesondere werden Unload-Ereignisse häufig in mobilen Browsern nicht ausgelöst, da es in mobilen Betriebssystemen viele Möglichkeiten gibt, einen Tab oder einen Browser zu schließen, ohne dass das unload-Ereignis ausgelöst wird. Bei XMLHttpRequest() war die Verwendung kleiner Nutzlasten die Wahl. Das ist jetzt eine Anforderung. Beide Alternativen haben gemäß der Spezifikation ein Uploadlimit von 64 KB pro Kontext.

Keepalive abrufen

Die Fetch API bietet eine robuste Möglichkeit für den Umgang mit Serverinteraktionen und eine konsistente Schnittstelle für die Verwendung in verschiedenen Plattform-APIs. Eine der Optionen ist keepalive. Damit wird sichergestellt, dass eine Anfrage unabhängig davon fortgesetzt wird, ob die Seite, die sie geöffnet hat, geöffnet bleibt:

window.addEventListener('unload', {
  fetch('/siteAnalytics', {
    method: 'POST',
    body: getStatistics(),
    keepalive: true
  });
}

Die Methode fetch() bietet den Vorteil, dass Sie genauer steuern können, was an den Server gesendet wird. Was ich im Beispiel nicht zeige, ist, dass fetch() auch ein Versprechen zurückgibt, das mit einem Response-Objekt aufgelöst wird. Ich habe versucht, beim Entfernen der Seite nichts zu unternehmen.

SendBeacon()

SendBeacon() nutzt die Fetch API im Hintergrund. Daher hat sie die gleiche Nutzlastbeschränkung von 64 KB und sorgt auch dafür, dass eine Anfrage nach dem Entfernen einer Seite fortgesetzt wird. Ihr Hauptvorteil ist die Einfachheit. Sie können Ihre Daten mit einer einzigen Codezeile senden:

window.addEventListener('unload', {
  navigator.sendBeacon('/siteAnalytics', getStatistics());
}

Fazit

Mit der erhöhten Verfügbarkeit von fetch() in Browsern wird XMLHttpRequest() hoffentlich irgendwann von der Webplattform entfernt. Die Browseranbieter sind sich einig, dass dies entfernt werden sollte, aber das wird einige Zeit in Anspruch nehmen. Die Einstellung eines der schlechtesten Anwendungsfälle ist ein erster Schritt, der die Nutzererfahrung für alle verbessert.

Foto von Matthew Hamilton auf Unsplash