Miglioramento della chiusura delle pagine nella funzione XMLHttpRequest() sincrono

Ridurre le navigazioni in ritardo

Joe Medley
Joe Medley

Capita spesso che una pagina o un'app presenti analisi o altri dati non inviati nel momento in cui un utente le chiude. Per evitare la perdita di dati, alcuni siti utilizzano una chiamata sincrona a XMLHttpRequest() per mantenere aperta la pagina o l'app finché i dati non vengono trasmessi al server. Non solo esistono modi migliori per salvare i dati, ma questa tecnica crea una cattiva esperienza utente ritardando la chiusura della pagina fino a diversi secondi.

Questa prassi deve cambiare e i browser stanno rispondendo. La specifica XMLHttpRequest() è già in programma per il ritiro e la rimozione. Chrome 80 fa il primo passo impedendo le chiamate sincrone all'interno di diversi gestori eventi, in particolare beforeunload, unload, pagehide e visibilitychange quando vengono attivati al momento della chiusura. Di recente, WebKit ha anche implementato un commit che apporta la stessa modifica del comportamento.

In questo articolo descrivo brevemente le opzioni per chi ha bisogno di tempo per aggiornare i propri siti e illustro le alternative a XMLHttpRequest().

Disattivazioni temporanee

Chrome non vuole semplicemente staccare il dispositivo XMLHttpRequest(), per questo motivo sono disponibili alcune opzioni di disattivazione temporanea. Per i siti su internet, è disponibile un provato dell'origine. In questo modo, aggiungi un token specifico per l'origine alle intestazioni delle pagine che consente le chiamate XMLHttpRequest() sincrone. Questa opzione termina poco prima del rilascio di Chrome 89, previsto per marzo 2021. I clienti di Chrome Enterprise possono anche utilizzare il flag dei criteri AllowSyncXHRInPageDismissal, che termina contemporaneamente.

Alternative

Indipendentemente da come invii i dati al server, è meglio evitare di attendere il caricamento della pagina per inviare tutti i dati contemporaneamente. Oltre a creare un'esperienza utente negativa, unload non è affidabile sui browser moderni e rischia di causare la perdita di dati se si verifica un problema. In particolare, gli eventi di unload spesso non si attivano sui browser per dispositivi mobili perché esistono diversi modi per chiudere una scheda o un browser sui sistemi operativi mobile senza che venga attivato l'evento unload. Con XMLHttpRequest(), l'utilizzo di payload di piccole dimensioni era una scelta. Ora è un requisito. Entrambe le alternative hanno un limite di caricamento di 64 KB per contesto, come richiesto dalla specifica.

Recupera keepalive

L'API Fetch offre un mezzo efficace per gestire le interazioni con il server e un'interfaccia coerente da utilizzare in diverse API di piattaforma. Tra le opzioni è presente keepalive, che garantisce che una richiesta continui indipendentemente dal fatto che la pagina che l'ha generata rimanga aperta o meno:

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

Il metodo fetch() ha il vantaggio di un maggiore controllo su ciò che viene inviato al server. Ciò che non mostro nell'esempio è che fetch() restituisce anche una promessa che si risolve con un oggetto Response. Dato che sto cercando di non ostacolare lo svuotamento della pagina, ho scelto di non fare nulla.

SendBeacon()

SendBeacon() in realtà utilizza l'API Fetch in background, motivo per cui ha la stessa limitazione di payload di 64 kB e perché garantisce anche che una richiesta continui dopo l'unload di una pagina. Il suo vantaggio principale è la semplicità. Ti consente di inviare i dati con una singola riga di codice:

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

Conclusione

Con l'aumento della disponibilità difetch() su tutti i browser, XMLHttpRequest() dovrebbe essere rimosso dalla piattaforma web a un certo punto. I fornitori di browser sono d'accordo sul fatto che debba essere rimosso, ma ci vorrà tempo. Il ritiro di uno dei casi d'uso peggiori è un primo passo per migliorare l'esperienza utente per tutti.

Foto di Matthew Hamilton su Unsplash