È normale che una pagina o un'app abbia dati di analisi o di altro tipo non inviati al momento della chiusura da parte di un utente. 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 passati al server. Non solo esistono modi migliori per salvare i dati, ma questa tecnica crea una pessima esperienza utente ritardando la chiusura della pagina fino a diversi secondi.
Questa pratica deve cambiare e i browser stanno rispondendo. La XMLHttpRequest()
specifica è già prevista per la deprecazione e
la rimozione. Chrome 80 compie il primo
passo vietando le chiamate sincrone all'interno di diversi gestori di eventi,
in particolare beforeunload, unload, pagehide, e visibilitychange quando
vengono attivati nella chiusura. WebKit ha anche recentemente eseguito il commit di una modifica del comportamento
simile.
Descriverò brevemente le opzioni per chi ha bisogno di tempo per aggiornare i propri siti e illustrerò le alternative a XMLHttpRequest().
Disattivazioni temporanee
Chrome vuole dare agli sviluppatori il tempo di rimuovere la dipendenza da XMLHttpRequest(), quindi abbiamo offerto opzioni di disattivazione temporanea.
Partecipa a una prova dell'origine
. In questo modo, aggiungi un token specifico dell'origine alle intestazioni della pagina che consente le chiamate sincrone XMLHttpRequest(). Questa opzione termina poco prima della spedizione di Chrome 89, prevista per marzo 2021. I clienti di Chrome Enterprise possono anche utilizzare il flag del criterio AllowSyncXHRInPageDismissal, che termina contemporaneamente.
Alternative
Indipendentemente dal modo in cui invii i dati al server, è consigliabile evitare di attendere lo scaricamento della pagina per inviare tutti i dati contemporaneamente. Oltre a creare una pessima esperienza utente, lo scaricamento non è affidabile sui browser moderni e rischia la perdita di dati in caso di problemi. In particolare, gli eventi di scaricamento spesso non vengono attivati sui browser
per dispositivi mobili
perché esistono molti 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.
Fetch keepalive
L'API Fetch
fornisce un mezzo efficace per gestire le interazioni con il server e un'interfaccia
coerente per l'utilizzo in diverse
API della piattaforma. Tra le opzioni c'è keepalive, che garantisce che una richiesta continui indipendentemente dal fatto che la pagina che l'ha effettuata rimanga aperta:
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. Nell'esempio non mostro che fetch() restituisce anche una promessa che si risolve con un oggetto Response. Poiché sto cercando di evitare lo scaricamento della pagina, ho scelto di non fare nulla.
SendBeacon()
SendBeacon()
utilizza l'API Fetch in background, motivo per cui ha lo stesso limite di payload di 64 KB e garantisce anche che una richiesta continui dopo lo scaricamento di una pagina. Il suo vantaggio principale è la semplicità. Ti consente di inviare i dati con una sola riga di codice:
window.addEventListener('unload', {
navigator.sendBeacon('/siteAnalytics', getStatistics());
}
Conclusione
Con la maggiore disponibilità di
fetch()
nei browser, si spera che XMLHttpRequest() venga rimosso
dalla piattaforma web. I fornitori di browser sono d'accordo sulla rimozione, ma ci vorrà del tempo. La deprecazione di uno dei suoi casi d'uso peggiori è un primo passo che migliora l'esperienza utente per tutti.