Miglioramento della chiusura delle pagine nella funzione XMLHttpRequest() sincrono

Ridurre i ritardi delle navigazioni

Mario Medley
Mario Medley

È normale che una pagina o un'app presenti dati analitici o altri dati non inviati nel momento in cui l'utente la chiude. Per evitare la perdita di dati, alcuni siti utilizzano una chiamata sincrona a XMLHttpRequest() per mantenere aperta la pagina o l'app fino a quando i relativi dati non vengono passati al server. Non solo esistono modi migliori per salvare i dati, ma questa tecnica crea anche un'esperienza utente negativa ritardando la chiusura della pagina di alcuni secondi.

Questa pratica deve cambiare e i browser stanno rispondendo. La specifica XMLHttpRequest() è già prevista per il ritiro e la rimozione. Chrome 80 fa il primo passo impedendo le chiamate sincrone all'interno di diversi gestori di eventi, in particolare beforeunload, unload, pagehide e visibilitychange quando vengono attivati durante l'eliminazione. Inoltre, WebKit ha recentemente ottenuto un commit che ha implementato lo stesso cambiamento del comportamento.

In questo articolo descriverò brevemente le opzioni disponibili per chi ha bisogno di tempo per aggiornare i propri siti e delinei le alternative a XMLHttpRequest().

Disattivazione temporanea

Chrome non vuole semplicemente staccare la spina su XMLHttpRequest(), motivo per cui sono disponibili alcune opzioni di disattivazione temporanea. Per i siti su internet, è disponibile una prova dell'origine. In questo modo, aggiungi alle intestazioni di pagina un token specifico dell'origine che consente le chiamate XMLHttpRequest() sincrone. Questa opzione termina poco prima della spedizione di Chrome 89, a marzo 2021. I clienti aziendali di Chrome possono anche utilizzare il flag del criterio AllowSyncXHRInPageDismissal, che termina contemporaneamente.

Alternative

Indipendentemente dalla modalità di invio dei dati al server, è meglio evitare di attendere l'unload della pagina per inviare tutti i dati contemporaneamente. A parte creare un'esperienza utente scadente, l'unload è inaffidabile sui browser moderni e rischia la perdita di dati se qualcosa va storto. In particolare, gli eventi di unload spesso non vengono attivati sui browser mobile perché esistono diversi modi per chiudere una scheda o un browser sui sistemi operativi mobile senza l'attivazione dell'evento unload. Con XMLHttpRequest() era la scelta di utilizzare payload di dimensioni ridotte. Ora è un requisito. Entrambe le alternative hanno un limite di caricamento di 64 kB per contesto, come richiesto dalla specifica.

Recupero keepalive

L'API Fetch offre uno strumento efficace per gestire le interazioni con il server e un'interfaccia coerente da utilizzare su API per piattaforme diverse. Tra le opzioni c'è keepalive, che garantisce che la richiesta continui indipendentemente dal fatto che la pagina che l'ha attivata rimanga aperta o meno:

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

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

SendBeacon()

SendBeacon() In realtà utilizza in background l'API Fetch, 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 vantaggio principale è la semplicità. Ti consente di inviare i dati con una singola riga di codice:

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

Conclusione

A causa della maggiore disponibilità di fetch() nei browser, speriamo che XMLHttpRequest() verrà rimosso dalla piattaforma web a un certo punto. I fornitori di browser concordano che la rimozione deve essere rimossa, ma richiede del tempo. Ritirare uno dei suoi casi d'uso peggiori è un primo passo che migliora l'esperienza utente per tutti.

Foto di Matthew Hamilton su Unsplash