De fetchLater API Origin-proefversie

Brendan Kenny
Brendan Kenny

Het is gebruikelijk 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 gebruikten ze vervolgens navigator.sendBeacon() of fetch() 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 achter een origin-proefversie die begint in versie 121 (uitgebracht in januari 2024) en loopt tot Chrome 126 (juli 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 een Request instantie.
  • Een optioneel options , dat de options van fetch() uitbreidt met een time-out genaamd activateAfter .

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 doorgaans 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 .

Meer informatie