fetchLater API 오리진 트라이얼

Brendan Kenny
Brendan Kenny

웹페이지가 서버로 다시 데이터 (또는 '비콘')를 전송해야 하는 경우가 많습니다. 사용자의 현재 세션에 대한 애널리틱스 데이터를 예로 들어보겠습니다. 이를 위해서는 탭이 닫혀 있거나 비콘이 전송되기 전에 사용자가 이탈한 경우 데이터가 누락될 위험 없이 일정하고 중복될 수 있는 요청을 줄이는 균형적인 조치가 필요합니다.

지금까지 개발자는 pagehidevisibilitychange 이벤트를 사용하여 페이지를 언로드할 때 포착한 다음 navigator.sendBeacon() 또는 fetch()keepalive와 함께 사용하여 데이터를 비콘했습니다. 그러나 이 두 이벤트는 사용자의 브라우저에 따라 다른 까다로운 특수한 상황을 발생시키며, 특히 모바일에서 이벤트가 전혀 도달하지 않는 경우도 있습니다.

fetchLater()는 이러한 복잡성을 단일 API 호출로 대체하기 위한 제안서입니다. 이름에서 알 수 있듯이, 페이지가 닫혀 있거나 사용자가 다른 곳으로 이동하더라도 향후 특정 시점에 요청이 이루어지도록 브라우저에 요청합니다.

fetchLater()는 Chrome에서 실제 사용자를 대상으로 Chrome 126 (2024년 7월)까지 실행되는 오리진 트라이얼 버전 121 (2024년 1월 출시)부터 테스트에 사용할 수 있습니다.

fetchLater() API

const fetchLaterResult = fetchLater(request, options);

fetchLater()는 두 개의 인수를 취하며 일반적으로 fetch()의 인수와 동일합니다.

  • request: 문자열 URL 또는 Request 인스턴스
  • activateAfter라는 제한 시간으로 fetch()options를 확장하는 선택적 options 객체입니다.

fetchLater()FetchLaterResult를 반환하며 현재 단일 읽기 전용 속성 activated만 포함되어 있습니다. 이 속성은 '나중에'가 지나고 가져오기가 완료되면 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

시간 초과 후 또는 페이지 로드 취소 시 요청을 실행하려는 경우(둘 중 먼저 발생한 경우를 적용) 옵션 객체는 fetch()의 옵션을 제한 시간(activateAfter)으로 확장합니다.

이렇게 하면 데이터가 가장 늦은 시점의 데이터 가져오기와 더 적절한 시점의 데이터 가져오기 사이에서 균형을 맞출 수 있습니다.

예를 들어, 사용자가 보통 업무일 내내 열어 두는 앱이 있는 경우, 사용자가 특정 시간이 끝나기 전에 언제든지 비콘을 종료하더라도 더 세부적인 분석을 보장하기 위해 시간 제한을 1시간으로 설정할 수 있습니다. 이후 1시간 동안의 분석을 위해 새 fetchLater()를 설정할 수 있습니다.

const hourInMilliseconds = 60 * 60 * 1000;
fetchLater('/endpoint/', {activateAfter: hourInMilliseconds});

사용 예

필드에서 코어 웹 바이탈을 측정할 때 발생하는 한 가지 문제는 사용자가 실제로 페이지를 떠날 때까지 성능 측정항목이 변경될 수 있다는 것입니다. 예를 들어 언제든지 더 큰 레이아웃 변경이 발생하거나 페이지가 상호작용에 반응하는 데 훨씬 더 오래 걸릴 수 있습니다.

하지만 페이지 로드 취소 시 버그가 있거나 불완전한 비커닝으로 인해 모든 성능 데이터가 손실될 위험이 있습니다. 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에서 문제와 의견을 제출해 주세요.

추가 정보