Пробная версия API fetchLater Origin

Брендан Кенни
Brendan Kenny

Веб-страницам часто приходится отправлять данные (или «маяки») обратно на свой сервер — например, аналитические данные для текущего сеанса пользователя. Для разработчиков это требует балансирования: сокращение постоянных, возможно, избыточных запросов без риска потери данных, если вкладка была закрыта или пользователь ушел до того, как можно было отправить маяк.

Традиционно разработчики использовали события pagehide visibilitychange , чтобы перехватить страницу при ее выгрузке, а затем использовали navigator.sendBeacon() или fetch() с keepalive для передачи данных маяка. Однако оба этих события имеют сложные ситуации, которые различаются в зависимости от браузера пользователя, а иногда события вообще не происходят, особенно на мобильных устройствах.

fetchLater() — это предложение заменить эту сложность одним вызовом API. Он делает именно то, что следует из названия: он просит браузер убедиться, что запрос сделан в какой-то момент в будущем, даже если страница будет закрыта или пользователь уйдет.

fetchLater() доступен в Chrome для тестирования с реальными пользователями в рамках пробной версии Origin, начиная с версии 121 (выпущенной в январе 2024 г.) и продолжающейся до Chrome 126 (июль 2024 г.).

API fetchLater()

const fetchLaterResult = fetchLater(request, options);

fetchLater() принимает два аргумента, обычно идентичных аргументам fetch() :

  • request – строковый URL-адрес или экземпляр Request .
  • Необязательный объект options , который расширяет options fetch() с помощью тайм-аута, называемого activateAfter .

fetchLater() возвращает FetchLaterResult , в настоящее время содержащий только одно activated свойство только для чтения, которому будет присвоено значение true , когда пройдет «позже» и будет выполнена выборка. Любой ответ на запрос fetchLater() отбрасывается.

request

Простейшее использование — это URL-адрес сам по себе:

fetchLater('/endpoint/');

Но, как и в случае с fetch() , для запроса fetchLater() можно установить большое количество параметров, включая пользовательские заголовки, поведение учетных данных, тело POST и signal AbortController для потенциальной его отмены .

fetchLater('/endpoint/', {
  method: 'GET',
  cache: 'no-store',
  mode: 'same-origin',
  headers: {Authorization: 'SUPER_SECRET'},
});

options

Объект options расширяет параметры fetch() с помощью таймаута activateAfter на тот случай, если вы хотите запустить запрос после таймаута или когда страница будет выгружена, в зависимости от того, что наступит раньше.

Это позволяет вам выбрать компромисс между получением данных в самый последний момент или тогда, когда это более своевременно.

Например, если у вас есть приложение, которое ваши пользователи обычно оставляют открытым в течение всего рабочего дня, вам может потребоваться установить тайм-аут в час, чтобы обеспечить более детальную аналитику, но при этом гарантировать маяк, если пользователь выйдет в любое время до наступления этого часа. вверх. Затем можно настроить новый 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() доступна в пробной версии Origin до версии Chrome 126. Дополнительную информацию о пробных версиях Origin см. в разделе «Начало работы с пробными версиями Origin».

Для локального тестирования fetchLater можно включить с помощью флага функций экспериментальной веб-платформы по адресу chrome://flags/#enable-experimental-web-platform-features . Его также можно включить, запустив Chrome из командной строки с помощью --enable-experimental-web-platform-features или более целевого флага --enable-features=FetchLaterAPI .

Если вы используете его на общедоступной странице, обязательно определите функцию, проверив, определен ли глобальный fetchLater перед его использованием:

if (globalThis.fetchLater) {
  // Set up beaconing using fetchLater().
  // ...
}

Обратная связь

Отзывы разработчиков необходимы для правильного создания новых веб-API, поэтому , пожалуйста, сообщайте о проблемах и отзывах на GitHub .

Больше информации