Bản dùng thử theo nguyên gốc của API findsau

Brendan Kenny
Brendan Kenny

Các trang web thường cần gửi dữ liệu (hoặc "báo hiệu") trở lại máy chủ của chúng — ví dụ như hãy xem xét dữ liệu phân tích cho phiên hiện tại của người dùng. Đối với các nhà phát triển, điều này đòi hỏi một hành động cân bằng: giảm liên tục, có thể dư thừa, các yêu cầu mà không có nguy cơ bỏ lỡ dữ liệu nếu thẻ bị đóng hoặc người dùng rời đi trước khi có thể gửi beacon.

Thông thường, nhà phát triển sử dụng các sự kiện pagehidevisibilitychange để nắm bắt trang khi trang huỷ tải, sau đó sử dụng navigator.sendBeacon() hoặc fetch() với keepalive làm dữ liệu beacon. Tuy nhiên, cả hai sự kiện này đều có những trường hợp góc khó và khác nhau dựa trên trình duyệt của người dùng và đôi khi các sự kiện không bao giờ xuất hiện, đặc biệt là trên thiết bị di động.

fetchLater() là một đề xuất để thay thế sự phức tạp này bằng một lệnh gọi API duy nhất. URL này hoạt động đúng như tên gọi của nó: yêu cầu trình duyệt đảm bảo rằng yêu cầu được thực hiện vào một thời điểm nào đó trong tương lai, ngay cả khi trang bị đóng hoặc người dùng rời khỏi.

fetchLater() có trong Chrome để thử nghiệm với người dùng thực tế sau bản dùng thử theo nguyên gốc bắt đầu từ phiên bản 121 (phát hành vào tháng 1 năm 2024), chạy cho đến Chrome 126 (tháng 7 năm 2024).

API fetchLater()

const fetchLaterResult = fetchLater(request, options);

fetchLater() nhận hai đối số, thường giống hệt với đối số của fetch():

  • request, một URL chuỗi hoặc thực thể Request.
  • Đối tượng options không bắt buộc, mở rộng options từ fetch() với thời gian chờ có tên là activateAfter.

fetchLater() trả về một FetchLaterResult, hiện chỉ chứa một thuộc tính chỉ có thể đọc duy nhất là activated. Thuộc tính này sẽ được thiết lập thành true khi giá trị "sau" đã trôi qua và quá trình tìm nạp đã được thực hiện. Mọi phản hồi đối với yêu cầu fetchLater() sẽ bị loại bỏ.

request

Cách sử dụng đơn giản nhất là sử dụng chính URL:

fetchLater('/endpoint/');

Tuy nhiên, giống như fetch(), bạn có thể đặt nhiều tuỳ chọn cho một yêu cầu fetchLater(), bao gồm cả tiêu đề tuỳ chỉnh, hành vi thông tin xác thực, nội dung POSTAbortController signal để có thể huỷ yêu cầu.

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

options

Đối tượng tuỳ chọn sẽ mở rộng các tuỳ chọn của fetch() với thời gian chờ, activateAfter, trong trường hợp bạn muốn kích hoạt yêu cầu sau khi hết thời gian chờ hoặc khi trang bị huỷ tải, tuỳ theo điều kiện nào đến trước.

Điều này cho phép bạn quyết định sự đánh đổi giữa việc nhận được dữ liệu tại thời điểm tuyệt đối có thể hoặc khi nó hợp thời hơn.

Ví dụ: nếu bạn có một ứng dụng mà người dùng thường mở trong cả ngày làm việc, bạn có thể muốn đặt thời gian chờ là một giờ để đảm bảo phân tích chi tiết hơn trong khi vẫn đảm bảo beacon nếu người dùng thoát bất kỳ lúc nào trước khi hết giờ đó. Sau đó, bạn có thể thiết lập một fetchLater() mới cho hoạt động phân tích trong giờ tiếp theo.

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

Ví dụ về cách sử dụng

Một vấn đề khi đo lường Các chỉ số quan trọng về trang web trong trường này là mọi chỉ số về hiệu suất đều có thể thay đổi cho đến khi người dùng thực sự rời khỏi một trang. Ví dụ: thay đổi lớn hơn về bố cục có thể xảy ra bất cứ lúc nào hoặc trang có thể mất nhiều thời gian hơn để phản hồi một lượt tương tác.

Tuy nhiên, bạn không muốn có nguy cơ mất tất cả dữ liệu hiệu suất do báo hiệu bị lỗi hoặc chưa hoàn tất khi tải trang. Đây là một ứng viên hoàn hảo cho chiến dịch fetchLater().

Trong ví dụ này, thư viện web-vitals.js được dùng để theo dõi các chỉ số và fetchLater() được dùng để báo cáo kết quả cho điểm cuối phân tích:

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);

Mỗi khi có bản cập nhật chỉ số, mọi fetchLater() đã lập lịch hiện có sẽ bị huỷ bằng AbortController và một fetchLater() mới sẽ được tạo kèm theo nội dung cập nhật đó.

Dùng thử fetchLater()

Như đã nêu, fetchLater() có sẵn trong bản dùng thử theo nguyên gốc cho đến Chrome 126. Xem bài viết "Bắt đầu dùng bản dùng thử theo nguyên gốc" để biết thông tin cơ bản về bản dùng thử theo nguyên gốc

Để kiểm thử cục bộ, bạn có thể bật fetchLater bằng cờ tính năng Nền tảng web thử nghiệm tại chrome://flags/#enable-experimental-web-platform-features. Bạn cũng có thể bật tính năng này bằng cách chạy Chrome từ dòng lệnh bằng --enable-experimental-web-platform-features hoặc cờ --enable-features=FetchLaterAPI được nhắm mục tiêu cụ thể hơn.

Nếu bạn sử dụng lệnh này trên trang công khai, hãy nhớ đảm bảo tính năng phát hiện bằng cách kiểm tra xem fetchLater chung đã được xác định hay chưa trước khi sử dụng:

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

Ý kiến phản hồi

Ý kiến phản hồi của nhà phát triển rất cần thiết để có được API web mới đúng cách, vì vậy, vui lòng gửi vấn đề và ý kiến phản hồi trên GitHub.

Thông tin khác