웹페이지에서 데이터 (또는 '표지')를 서버로 다시 전송해야 하는 경우가 많습니다. 예를 들어 사용자의 현재 세션에 대한 분석 데이터를 생각해 보세요. 개발자는 이때 균형을 유지해야 합니다. 비콘을 전송하기 전에 탭이 닫히거나 사용자가 탐색을 중단한 경우 데이터 누락을 방지하면서 끊임없이 반복될 수 있는 요청을 줄여야 합니다.
기존에는 개발자가 pagehide
및 visibilitychange
이벤트를 사용하여 페이지가 언로드될 때 페이지를 포착한 다음 navigator.sendBeacon()
또는 fetch()
와 keepalive
를 사용하여 데이터를 비콘으로 전송했습니다. 그러나 이 두 이벤트 모두 사용자의 브라우저에 따라 달라지는 어려운 특이 사례가 있으며, 특히 모바일에서는 이벤트가 전혀 도착하지 않는 경우도 있습니다.
fetchLater()
는 이러한 복잡성을 단일 API 호출로 대체하기 위한 제안입니다. 이름에서 알 수 있듯이 페이지가 닫히거나 사용자가 페이지를 벗어나도 향후 특정 시점에 요청이 이루어지도록 브라우저에 요청합니다.
fetchLater()
는 Chrome에서 오리진 트라이얼을 통해 실제 사용자를 대상으로 테스트할 수 있으며, 이 트라이얼은 2024년 1월에 출시된 버전 121부터 시작되어 2024년 9월 3일까지 진행됩니다.
fetchLater()
API
const fetchLaterResult = fetchLater(request, options);
fetchLater()
는 일반적으로 fetch()
의 인수와 동일한 두 인수를 사용합니다.
request
: 문자열 URL 또는Request
인스턴스입니다.- 선택적
options
객체로,activateAfter
라는 제한 시간으로fetch()
의options
를 확장합니다.
fetchLater()
는 현재 읽기 전용 속성 activated
하나만 포함하는 FetchLaterResult
를 반환하며, 이 속성은 '나중에'가 지나고 가져오기가 완료되면 true
로 설정됩니다. fetchLater()
요청에 대한 응답은 모두 삭제됩니다.
request
가장 간단한 사용법은 URL 자체입니다.
fetchLater('/endpoint/');
하지만 fetch()
와 마찬가지로 fetchLater()
요청에는 맞춤 헤더, 사용자 인증 정보 동작, POST
본문, AbortController
signal
(잠재적으로 취소할 수 있음) 등 다양한 옵션을 설정할 수 있습니다.
fetchLater('/endpoint/', {
method: 'GET',
cache: 'no-store',
mode: 'same-origin',
headers: {Authorization: 'SUPER_SECRET'},
});
options
options 객체는 제한 시간 activateAfter
으로 fetch()
의 옵션을 확장합니다. 제한 시간 후 또는 페이지가 언로드될 때(둘 중 먼저 오는 경우) 요청을 실행하려는 경우입니다.
이를 통해 가능한 한 마지막 순간에 데이터를 가져올지 아니면 더 시의적절한 시점에 가져올지 결정할 수 있습니다.
예를 들어 사용자가 일반적으로 하루 종일 열어 두는 앱이 있는 경우 1시간의 시간 제한을 설정하여 더 세부적인 분석을 수행하는 동시에 1시간이 지나기 전에 사용자가 종료한 경우 비콘을 보장할 수 있습니다. 그러면 다음 1시간 동안의 분석을 위해 새 fetchLater()
를 설정할 수 있습니다.
const hourInMilliseconds = 60 * 60 * 1000;
fetchLater('/endpoint/', {activateAfter: hourInMilliseconds});
사용 예
현장에서 Core Web Vitals를 측정할 때 발생하는 한 가지 문제는 사용자가 실제로 페이지를 나가기 전까지 성능 측정항목이 변경될 수 있다는 점입니다. 예를 들어 언제든지 더 큰 레이아웃 전환이 발생하거나 페이지가 상호작용에 응답하는 데 더 오래 걸릴 수 있습니다.
하지만 페이지 언로드 시 버그가 있거나 불완전한 비콘으로 인해 모든 실적 데이터가 손실될 위험을 감수하고 싶지는 않습니다. fetchLater()
에 적합한 후보입니다.
이 예에서는 web-vitals.js 라이브러리를 사용하여 측정항목을 모니터링하고 fetchLater()
를 사용하여 결과를 분석 엔드포인트에 보고합니다.
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);
측정항목 업데이트가 들어올 때마다 기존의 예약된 fetchLater()
가 AbortController
로 취소되고 업데이트가 포함된 새 fetchLater()
가 생성됩니다.
fetchLater()
사용해 보기
앞서 설명한 대로 fetchLater()
는 Chrome 126까지 오리진 트라이얼로 제공됩니다. 출처 실험에 관한 배경 정보는 '출처 실험 시작하기'를 참고하세요.
로컬 테스트의 경우 chrome://flags/#enable-experimental-web-platform-features
에서 실험용 웹 플랫폼 기능 플래그를 사용하여 fetchLater
를 사용 설정할 수 있습니다. 명령줄에서 --enable-experimental-web-platform-features
또는 더 타겟팅된 --enable-features=FetchLaterAPI
플래그를 사용하여 Chrome을 실행하여 사용 설정할 수도 있습니다.
공개 페이지에서 사용하는 경우 전역 fetchLater
가 정의되어 있는지 확인하여 기능을 감지해야 합니다.
if (globalThis.fetchLater) {
// Set up beaconing using fetchLater().
// ...
}
의견
새로운 웹 API를 올바르게 사용하려면 개발자 의견이 필수적이므로 GitHub에서 문제 및 의견을 제출해 주세요.