Halaman web biasanya perlu mengirim data (atau "beacon") kembali ke servernya—misalnya, data analisis untuk sesi pengguna saat ini. Bagi developer, hal ini memerlukan tindakan penyeimbangan: mengurangi permintaan yang konstan, mungkin redundan, tanpa risiko data yang terlewat jika tab ditutup atau pengguna keluar sebelum beacon dapat dikirim.
Secara tradisional, developer telah menggunakan peristiwa pagehide
dan visibilitychange
untuk menangkap halaman saat di-unload, lalu menggunakan navigator.sendBeacon()
atau fetch()
dengan keepalive
untuk beacon data. Namun, kedua peristiwa ini memiliki kasus ekstrem yang sulit yang berbeda berdasarkan browser pengguna, dan terkadang peristiwa tersebut tidak pernah muncul sama sekali—terutama di perangkat seluler.
fetchLater()
adalah proposal untuk mengganti kompleksitas ini dengan satu panggilan API. Fungsi ini berfungsi persis seperti namanya: meminta browser untuk memastikan permintaan dibuat pada suatu waktu di masa mendatang, meskipun halaman ditutup atau pengguna beralih ke halaman lain.
fetchLater()
tersedia di Chrome untuk pengujian dengan pengguna sungguhan dalam uji coba origin mulai versi 121 (dirilis pada Januari 2024), yang berjalan hingga 3 September 2024.
fetchLater()
API
const fetchLaterResult = fetchLater(request, options);
fetchLater()
menggunakan dua argumen, yang umumnya identik dengan argumen fetch()
:
request
, baik URL string maupun instanceRequest
.- Objek
options
opsional, yang memperluasoptions
darifetch()
dengan waktu tunggu yang disebutactivateAfter
.
fetchLater()
menampilkan FetchLaterResult
, yang saat ini hanya berisi satu properti hanya baca activated
, yang akan ditetapkan ke true
saat "nanti" telah berlalu dan pengambilan telah dilakukan. Setiap respons terhadap permintaan fetchLater()
akan dihapus.
request
Penggunaan yang paling sederhana adalah URL itu sendiri:
fetchLater('/endpoint/');
Namun, seperti fetch()
, banyak opsi yang dapat ditetapkan pada permintaan fetchLater()
, termasuk header kustom, perilaku kredensial, isi POST
, dan AbortController
signal
untuk berpotensi membatalkannya.
fetchLater('/endpoint/', {
method: 'GET',
cache: 'no-store',
mode: 'same-origin',
headers: {Authorization: 'SUPER_SECRET'},
});
options
Objek opsi memperluas opsi fetch()
dengan waktu tunggu, activateAfter
, jika Anda ingin mengaktifkan permintaan setelah waktu tunggu atau saat halaman dihapus muatannya, mana saja yang lebih dulu.
Hal ini memungkinkan Anda memutuskan kompromi antara mendapatkan data pada saat terakhir atau saat lebih tepat waktu.
Misalnya, jika Anda memiliki aplikasi yang biasanya tetap dibuka oleh pengguna sepanjang hari kerja, Anda mungkin ingin memiliki waktu tunggu selama satu jam untuk memastikan analisis yang lebih terperinci sambil tetap menjamin beacon jika pengguna keluar kapan saja sebelum jam tersebut habis. fetchLater()
baru kemudian dapat disiapkan untuk analisis satu jam berikutnya.
const hourInMilliseconds = 60 * 60 * 1000;
fetchLater('/endpoint/', {activateAfter: hourInMilliseconds});
Contoh penggunaan
Salah satu masalah saat mengukur Data Web Inti di lapangan adalah metrik performa dapat berubah hingga pengguna benar-benar meninggalkan halaman. Misalnya, pergeseran tata letak yang lebih besar dapat terjadi kapan saja, atau halaman mungkin memerlukan waktu lebih lama untuk merespons interaksi.
Namun, Anda tidak ingin mengambil risiko kehilangan semua data performa karena beaconing yang bermasalah atau tidak lengkap saat halaman di-unload. Ini adalah kandidat yang sempurna untuk fetchLater()
.
Dalam contoh ini, library web-vitals.js digunakan untuk memantau metrik, dan fetchLater()
digunakan untuk melaporkan hasilnya ke endpoint analisis:
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);
Setiap kali pembaruan metrik masuk, fetchLater()
terjadwal yang ada akan dibatalkan dengan AbortController
dan fetchLater()
baru akan dibuat dengan menyertakan pembaruan.
Coba fetchLater()
Sebagaimana dinyatakan, fetchLater()
tersedia dalam uji coba origin hingga Chrome 126. Lihat "Memulai uji coba origin" untuk mengetahui informasi latar belakang tentang uji coba origin
Untuk pengujian lokal, fetchLater
dapat diaktifkan dengan flag fitur Platform Web Eksperimental di chrome://flags/#enable-experimental-web-platform-features
. Fitur ini juga dapat diaktifkan dengan menjalankan Chrome dari command line dengan --enable-experimental-web-platform-features
, atau flag --enable-features=FetchLaterAPI
yang lebih ditargetkan.
Jika Anda menggunakannya di halaman publik, pastikan untuk mendeteksi fitur dengan memeriksa apakah fetchLater
global ditentukan sebelum menggunakannya:
if (globalThis.fetchLater) {
// Set up beaconing using fetchLater().
// ...
}
Masukan
Masukan developer sangat penting untuk mendapatkan API web baru yang tepat, jadi laporkan masalah dan masukan di GitHub.