Het komt vaak voor dat webpagina's gegevens (of 'baken') terug moeten sturen naar hun server. Denk bijvoorbeeld aan analysegegevens voor de huidige sessie van een gebruiker. Voor ontwikkelaars vereist dit een evenwichtsoefening: het verminderen van constante, mogelijk redundante, verzoeken zonder het risico te lopen dat gegevens worden gemist als het tabblad wordt gesloten of de gebruiker weg navigeert voordat een baken kan worden verzonden.
Traditioneel gebruikten ontwikkelaars pagehide
en visibilitychange
om de pagina op te vangen terwijl deze werd geladen, en vervolgens navigator.sendBeacon()
of fetch()
te gebruiken met keepalive
to beacon-gegevens. Beide gebeurtenissen hebben echter lastige situaties die verschillen afhankelijk van de browser van de gebruiker, en soms komen de gebeurtenissen helemaal niet aan, vooral niet op mobiele apparaten.
fetchLater()
is een voorstel om deze complexiteit te vervangen door een enkele API-aanroep. Het doet precies wat de naam doet vermoeden: het vraagt de browser om ervoor te zorgen dat er op een bepaald moment in de toekomst een verzoek wordt gedaan, zelfs als de pagina wordt gesloten of de gebruiker weg navigeert.
fetchLater()
is beschikbaar in Chrome om te testen met echte gebruikers via een origin-proefversie die begint in versie 121 (uitgebracht in januari 2024) en loopt tot 3 september 2024.
De fetchLater()
-API
const fetchLaterResult = fetchLater(request, options);
fetchLater()
heeft twee argumenten nodig, doorgaans identiek aan die van fetch()
:
- Het
request
, een string-URL of eenRequest
instantie. - Een optioneel
options
, dat deoptions
vanfetch()
uitbreidt met een time-out genaamdactivateAfter
.
fetchLater()
retourneert een FetchLaterResult
, die momenteel slechts één alleen-lezen activated
bevat, die op true
wordt ingesteld wanneer "later" is verstreken en de ophaalactie is uitgevoerd. Elk antwoord op het fetchLater()
verzoek wordt genegeerd.
request
Het eenvoudigste gebruik is een URL op zichzelf:
fetchLater('/endpoint/');
Maar net als fetch()
kan een groot aantal opties worden ingesteld op een fetchLater()
verzoek, inclusief aangepaste headers, gedrag van inloggegevens, een POST
body en een AbortController
signal
om het mogelijk te annuleren .
fetchLater('/endpoint/', {
method: 'GET',
cache: 'no-store',
mode: 'same-origin',
headers: {Authorization: 'SUPER_SECRET'},
});
options
Het optieobject breidt de opties van fetch()
uit met een time-out, activateAfter
, voor het geval u het verzoek wilt activeren na de time-out of wanneer de pagina wordt verwijderd, afhankelijk van wat zich het eerst voordoet.
Hierdoor kunt u de afweging maken tussen het verkrijgen van gegevens op het absoluut laatst mogelijke moment of wanneer dit beter op het juiste moment is.
Als u bijvoorbeeld een app heeft die uw gebruikers gewoonlijk de hele werkdag open houden, wilt u misschien een time-out van een uur instellen om gedetailleerdere analyses te garanderen, terwijl u toch een baken kunt garanderen als de gebruiker op enig moment vóór dat uur de app verlaat. omhoog. Een nieuwe fetchLater()
kan vervolgens worden ingesteld voor het volgende uur aan analyses.
const hourInMilliseconds = 60 * 60 * 1000;
fetchLater('/endpoint/', {activateAfter: hourInMilliseconds});
Voorbeeld gebruik
Een probleem bij het meten van Core Web Vitals in het veld is dat alle prestatiestatistieken kunnen veranderen totdat de gebruiker daadwerkelijk een pagina verlaat. Er kunnen bijvoorbeeld op elk moment grotere lay-outverschuivingen optreden, of het kan zelfs nog langer duren voordat de pagina op een interactie reageert.
U wilt echter niet het risico lopen alle prestatiegegevens kwijt te raken als gevolg van bugs of onvolledige beaconing bij het verwijderen van de pagina. Het is een perfecte kandidaat voor fetchLater()
.
In dit voorbeeld wordt de bibliotheek web-vitals.js gebruikt om de statistieken te monitoren, en wordt fetchLater()
gebruikt om de resultaten te rapporteren aan een analyse-eindpunt:
import {onCLS, onINP, onLCP} from 'web-vitals';
const queue = new Set();
let fetchLaterController;
let fetchLaterResult;
function updateQueue(metricUpdate) {
// If there was an already complete request for whatever
// reason, clear out the queue of already-sent updates.
if (fetchLaterResult?.activated) {
queue.clear();
}
queue.add(metricUpdate);
// JSON.stringify used here for simplicity and will likely include
// more data than you need. Replace with a preferred serialization.
const body = JSON.stringify([...queue]);
// Abort any existing `fetchLater()` and schedule a new one with
// the update included.
fetchLaterController?.abort();
fetchLaterController = new AbortController();
fetchLaterResult = fetchLater('/analytics', {
method: 'POST',
body,
signal: fetchLaterController.signal,
activateAfter: 60 * 60 * 1000, // Timeout to ensure timeliness.
});
}
onCLS(updateQueue);
onINP(updateQueue);
onLCP(updateQueue);
Elke keer dat er een metrische update binnenkomt, wordt een bestaande geplande fetchLater()
geannuleerd met een AbortController
en wordt er een nieuwe fetchLater()
gemaakt waarin de update is opgenomen.
Probeer fetchLater()
uit
Zoals gezegd is fetchLater()
beschikbaar in een origin-proefversie tot Chrome 126. Zie " Aan de slag met origin-proefversies " voor achtergrondinformatie over origin-proefversies
Voor lokaal testen kan fetchLater
worden ingeschakeld met de Experimental Web Platform-functiesvlag op chrome://flags/#enable-experimental-web-platform-features
. Het kan ook worden ingeschakeld door Chrome vanaf de opdrachtregel uit te voeren met --enable-experimental-web-platform-features
, of de meer gerichte vlag --enable-features=FetchLaterAPI
.
Als u het op een openbare pagina gebruikt, zorg er dan voor dat u functiedetectie uitvoert door te controleren of de globale fetchLater
is gedefinieerd voordat u deze gebruikt:
if (globalThis.fetchLater) {
// Set up beaconing using fetchLater().
// ...
}
Feedback
Feedback van ontwikkelaars is essentieel om nieuwe web-API's goed te krijgen, dus dien problemen en feedback in op GitHub .