Çoğu analiz, telemetri ve Core Web Vitals analiz verisi, kullanıcıya yanıt vermekten daha düşük önceliklidir. Bu nedenle, bu verileri göndermeyi kullanıcı sayfadan ayrılana kadar güvenle erteleyebilirsiniz. Anlık güncellemeler sunmanız gereken durumlar bu kuralın istisnasıdır. Bu durumda zamanlama önemlidir.
İşaretçileri en aza indirirken gerçek zamanlı analiz güncellemeleri sağlamanın en iyi yolu, activateAfter yapılandırma seçeneğiyle fetchLater() kullanmaktır. Bu sayede, belirli bir zaman aralığında gerçekleşen tüm analiz etkinliklerini tek bir işaretçide etkili bir şekilde birleştirebilir ve toplu olarak işleyebilirsiniz. Bu işaretçi, kullanıcı zaman aşımı süresi dolmadan sayfadan ayrılsa bile güvenilir bir şekilde gönderilir.
Nasıl uygulanır?
İsteği planlayın: Alakalı analiz verileri kullanılabilir hale gelir gelmez veri yükünüzle
fetchLater()yöntemini çağırın ve biractivateAfterdeğeri iletin. Bu işlem, verileri bu süre geçtikten sonra veya kullanıcı sayfadan daha önce ayrılırsa gönderilmek üzere sıraya alır.Birden fazla etkinliği toplu olarak işleme:
activateAfterzaman aşımı süresi dolmadan önce yeni bir analiz etkinliği gerçekleşirse önceden planlanan isteği iptal edin ve tek bir yükte tam etkinlik sırasıylafetchLater()işlevini tekrar (aynıactivateAfterdeğeriyle) çağırın.Zaman aşımı süresi dolduğunda etkinlik sırasını sıfırla: Planlanan işaretçi başarıyla gönderildikten sonra yeni bir analiz etkinliği gerçekleşirse (ör.
fetchLater()sonucununactivateddeğeritrueise) etkinlik sırasını sıfırlayın.Gerisini tarayıcıya bırakın: Kullanıcı,
activateAfterzaman aşımı süresi dolmadan önce sayfadan ayrılır veya sekmeyi kapatırsa tarayıcı, en sonfetchLater()çağrınızdaki yükü güvenilir bir şekilde göndermeye devam eder.
Örnek kod
Bu kod, bir sayfadaki tüm load ve click etkinliklerini izler ve 10 saniyelik zaman aşımı süresi içinde gerçekleşen tüm etkinlikleri gruplandırır.
// Replace with your analytics endpoint.
const ANALYTICS_ENDPOINT = '/path/to/analytics/endpoint';
// Replace with a time window of your choice. All analytics events that
// occur within this time window will be batched together.
const BATCH_WINDOW = 10 * 1000;
// The maximum number of events to batch. Pick a number that is unlikely
// to overflow the fetchLater() quota for the page.
const MAX_QUEUE_SIZE = 100;
const eventQueue = [];
let fetchLaterResult;
let fetchLaterController;
function trackEvent(eventData) {
// If the previously queued beacon has already been sent, or if the
// max queue size has been met, reset the queue.
if (fetchLaterResult?.activated || eventQueue.length > MAX_QUEUE_SIZE) {
fetchLaterController = null;
fetchLaterResult = null;
eventQueue.length = 0;
}
eventQueue.push(eventData);
// Abort any pending beacons before creating a new one.
if (fetchLaterController) {
fetchLaterController.abort();
}
fetchLaterController = new AbortController();
// Schedule a fetch for the events to be sent when the batch window expires.
// IMPORTANT: wrap the call in a try/catch to handle quota errors.
try {
fetchLaterResult = fetchLater(ANALYTICS_ENDPOINT, {
method: 'POST',
headers: {'content-type': 'application/json'},
body: JSON.stringify(eventQueue),
signal: fetchLaterController.signal,
activateAfter: BATCH_WINDOW,
});
} catch (error) {
// Handle errors as needed.
}
}
// Track page loads.
window.addEventListener('load', () => {
trackEvent({type: 'page_load'});
});
// Track click events.
window.addEventListener('click', (event) => {
trackEvent({type: 'click', target: serializeElement(event.target)});
});
En İyi Uygulamalar
- Birbirine yakın zamanlarda gerçekleşen birden fazla analiz etkinliğini toplu olarak işlemek için
fetchLater()ileactivateAfterseçeneğini KULLANIN. - Yeni bir analiz etkinliği gerçekleştiğinde beklemedeki getirme işlemini iptal etmek için
AbortControllerKULLANIN. - MUTLAKA çok fazla etkinliği bir araya getirip
fetchLater()kotasını (şu anda kaynak başına yaklaşık 64 KB) aşmadığınızdan emin olun. - MUTLAKA kota hatalarını işlemek için
fetchLater()çağrılarınıtry/catchiçine alın. globalThisüzerindefetchLater()'nin varlığını tespit etmek için özellik algılamayı KULLANIN ve API'yi desteklemeyen tarayıcılar için bir yedek strateji uygulayın.- İstek gövdesi için
ReadableStreamnesnesi KULLANMAYIN. Aksi takdirde hata alırsınız.
Tarayıcı desteği ve yedek stratejiler
Bu nedenle, genellikle bir yedek strateji gerekir.
Ancak bu API'nin daha yüksek güvenilirlik ve performans avantajları göz önüne alındığında, tarayıcı destekliyorsa fetchLater() kullanılmalıdır.
fetchLater() polyfill
Desteklenmeyen tarayıcılarda API'yi mümkün olduğunca yakın bir şekilde uygulayan aşağıdaki minimal fetchLater() polyfill'i kullanın.
Bu polyfill ile ilgili tek önemli davranış farkı, kullanıcı sayfadan ayrıldığında yükü göndermek yerine, sayfanın visibilityState değeri "gizli" olarak değiştiğinde göndermesidir. Bu, günümüzde yaygın olarak kullanılan en güvenilir oturum sonu sinyalidir.
globalThis.fetchLater ??= function fetchLater(url, init = {}) {
let timeoutHandle;
let activated = false;
function sendNow() {
if (!(init.signal && init.signal.aborted)) {
// Use fetch keepalive if the browser supports it or if custom fetch
// parameters are specified (e.g. custom headers or methods).
// Otherwise fall back to `navigator.sendBeacon()`.
if (
'keepalive' in Request.prototype ||
init.method !== 'POST' ||
init.headers
) {
fetch(url, Object.assign({}, init, {keepalive: true}));
activated = true;
} else {
activated = navigator.sendBeacon(url, init.body);
}
}
destroy();
}
function destroy() {
document.removeEventListener('visibilitychange', sendNow);
clearTimeout(timeoutHandle);
}
if (document.visibilityState === 'hidden') {
// If the beacon was created while the page is already hidden, send data
// ASAP but wait until the next microtask to allow all sync code to run.
queueMicrotask(sendNow);
} else {
document.addEventListener('visibilitychange', sendNow);
if (typeof init.activateAfter === 'number' && init.activateAfter >= 0) {
timeoutHandle = setTimeout(sendNow, init.activateAfter);
}
}
if (init.signal) {
init.signal.addEventListener('abort', destroy);
}
return {
get activated() {
return activated;
},
};
};