Amélioration de la fermeture des pages dans XMLHttpRequest() synchrones

Réduire les navigations retardées

Joe Medley
Joe Medley

Il est courant qu'une page ou une application comporte des données analytiques ou d'autres données non envoyées au moment où un utilisateur la ferme. Pour éviter toute perte de données, certains sites utilisent un appel synchrone à XMLHttpRequest() pour garder la page ou l'application ouverte jusqu'à ce que ses données soient transmises au serveur. Il existe de meilleures façons d'enregistrer des données. De plus, cette technique offre une mauvaise expérience utilisateur en retardant la fermeture de la page jusqu'à plusieurs secondes.

Cette pratique doit changer, et les navigateurs y répondent. La spécification XMLHttpRequest() est déjà programmée pour être abandonnée et supprimée. Chrome 80 fait le premier pas en interdisant les appels synchrones dans plusieurs gestionnaires d'événements, en particulier beforeunload, unload, pagehide et visibilitychange lorsqu'ils sont déclenchés lors du rejet. De plus, WebKit a récemment obtenu un engagement pour la mise en œuvre du même changement de comportement.

Dans cet article, je décris brièvement les options disponibles pour les utilisateurs qui ont besoin de temps pour mettre à jour leurs sites et les alternatives à XMLHttpRequest().

Désactivations temporaires

Chrome ne veut pas simplement arrêter XMLHttpRequest(), c'est pourquoi quelques options de désactivation temporaire sont disponibles. Pour les sites sur Internet, un essai d'origine est disponible. Vous ajoutez ainsi un jeton spécifique à l'origine à vos en-têtes de page, ce qui permet d'effectuer des appels XMLHttpRequest() synchrones. Cette option prendra fin peu de temps avant le lancement de Chrome 89, soit en mars 2021. Les clients Chrome Enterprise peuvent également utiliser l'indicateur de règle AllowSyncXHRInPageDismissal, qui prend fin en même temps.

Autres solutions

Quelle que soit la méthode utilisée pour renvoyer des données au serveur, il est préférable d'éviter d'attendre la fin du déchargement de la page pour envoyer toutes les données en même temps. En plus de créer une mauvaise expérience utilisateur, le déchargement n'est pas fiable sur les navigateurs modernes et risque de perdre des données en cas de problème. Plus précisément, les événements de déchargement ne se déclenchent souvent pas sur les navigateurs mobiles, car il existe de nombreuses façons de fermer un onglet ou un navigateur sur les systèmes d'exploitation mobiles sans que l'événement unload ne se déclenche. Avec XMLHttpRequest(), l'utilisation de petites charges utiles était un choix. C'est maintenant obligatoire. Les deux autres options ont une limite d'importation de 64 Ko par contexte, comme l'exige la spécification.

Demande keepalive de récupération

L'API Fetch fournit un moyen efficace de gérer les interactions avec le serveur et une interface cohérente à utiliser dans différentes API de plate-forme. Parmi ses options, keepalive, qui garantit qu'une requête continue, que la page qui l'a créée reste ouverte ou non:

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

La méthode fetch() présente l'avantage de mieux contrôler ce qui est envoyé au serveur. Ce que je ne montre pas dans l'exemple, c'est que fetch() renvoie également une promesse qui se résout avec un objet Response. Comme je ne veux pas gêner le déchargement de la page, j'ai choisi de ne rien faire avec.

SendBeacon()

SendBeacon() utilise en réalité l'API Fetch en interne, c'est pourquoi elle présente la même limite de charge utile de 64 ko et qu'elle garantit également la poursuite d'une requête après le vidage d'une page. Son principal avantage est sa simplicité. Il vous permet d'envoyer vos données avec une seule ligne de code:

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

Conclusion

Avec l'augmentation de la disponibilité de fetch() dans les navigateurs, XMLHttpRequest() devrait à terme être supprimé de la plate-forme Web. Les fournisseurs de navigateurs s'accordent à dire qu'il doit être supprimé, mais cela prendra du temps. La suppression de l'un de ses pires cas d'utilisation est une première étape qui améliore l'expérience utilisateur pour tous.

Photo par Matthew Hamilton, publiée sur Unsplash