Verbessertes Schließen von Seiten im synchronen XMLHttpRequest()

Verzögerte Navigationen reduzieren

Joe Medley
Joe Medley

Es ist normal, dass auf einer Seite oder in einer App nicht eingereichte Analysedaten oder andere Daten vorhanden sind, wenn ein Nutzer sie schließt. Um Datenverluste zu vermeiden, verwenden einige Websites einen synchronen Aufruf von XMLHttpRequest(), um die Seite oder App offen zu halten, bis die Daten an den Server übergeben wurden. Es gibt nicht nur bessere Möglichkeiten, Daten zu speichern, sondern diese Methode führt auch zu einer schlechten Nutzererfahrung, da das Schließen der Seite um bis zu mehrere Sekunden verzögert wird.

Diese Vorgehensweise muss geändert werden und die Browser reagieren darauf. Die XMLHttpRequest()-Spezifikation wird eingestellt und entfernt. In Chrome 80 wird der erste Schritt unternommen, indem synchrone Aufrufe in mehreren Ereignishandlern nicht mehr zulässig sind, insbesondere beforeunload, unload, pagehide und visibilitychange, wenn sie beim Schließen ausgelöst werden. In WebKit wurde vor Kurzem auch ein Commit mit derselben Verhaltensänderung veröffentlicht.

In diesem Artikel werden kurz Optionen für diejenigen beschrieben, die Zeit für die Aktualisierung ihrer Websites benötigen, und es werden Alternativen zu XMLHttpRequest() erläutert.

Vorübergehende Deaktivierung

Chrome möchte XMLHttpRequest() nicht einfach einstellen. Deshalb gibt es einige vorübergehende Deaktivierungsoptionen. Für Websites im Internet ist ein Testzeitraum für den Ursprung verfügbar. Damit fügen Sie den Seitenheadern ein ursprungsspezifisches Token hinzu, das synchrone XMLHttpRequest()-Aufrufe ermöglicht. Diese Option wird kurz vor der Veröffentlichung von Chrome 89 eingestellt, also irgendwann im März 2021. Chrome Enterprise-Kunden können auch das Richtlinien-Flag AllowSyncXHRInPageDismissal verwenden, das zum selben Zeitpunkt endet.

Alternativen

Unabhängig davon, wie Sie Daten an den Server zurücksenden, sollten Sie nicht warten, bis die Seite vollständig ausgeblendet ist, um alle Daten gleichzeitig zu senden. Abgesehen davon, dass das Entladen die Nutzererfahrung beeinträchtigt, ist das Entladen in modernen Browsern unzuverlässig und riskiert einen Datenverlust, wenn etwas schiefgeht. Unload-Ereignisse werden häufig nicht in mobilen Browsern ausgelöst, da es viele Möglichkeiten gibt, einen Tab oder Browser auf mobilen Betriebssystemen zu schließen, ohne dass das unload-Ereignis ausgelöst wird. Bei XMLHttpRequest() war die Verwendung kleiner Nutzlasten eine Option. Jetzt ist es eine Anforderung. Für beide Alternativen gilt gemäß der Spezifikation ein Upload-Limit von 64 KB pro Kontext.

Fetch-Keepalive

Die Fetch API bietet eine robuste Möglichkeit zum Umgang mit Serverinteraktionen und eine einheitliche Schnittstelle zur Verwendung in verschiedenen Plattform-APIs. Zu den Optionen gehört keepalive, mit der eine Anfrage fortgesetzt wird, unabhängig davon, ob die Seite, auf der sie gesendet wurde, geöffnet bleibt:

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

Die Methode fetch() bietet den Vorteil, dass Sie mehr Kontrolle darüber haben, was an den Server gesendet wird. Was im Beispiel nicht zu sehen ist: fetch() gibt auch ein Versprechen zurück, das mit einem Response-Objekt aufgelöst wird. Da ich das Entladen der Seite nicht behindern möchte, habe ich nichts damit gemacht.

SendBeacon()

SendBeacon() verwendet intern die Fetch API. Daher ist die Nutzlast auf 64 KB begrenzt und eine Anfrage wird auch nach dem Entladen einer Seite fortgesetzt. Der Hauptvorteil besteht in der Einfachheit. Sie können Ihre Daten mit einer einzigen Codezeile einreichen:

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

Fazit

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

Foto von Matthew Hamilton auf Unsplash