גרסת המקור לניסיון של ProvideLater API

Brendan Kenny
Brendan Kenny

לעיתים קרובות דפי אינטרנט צריכים לשלוח נתונים (או 'משׂואת רשת') חזרה לשרת שלהם. כדוגמה, לחשוב על נתוני ניתוח לגבי הסשן הנוכחי של המשתמש. כשמדובר במפתחים, נדרש איזון: אם הכרטיסייה נסגרה או שהמשתמש לא יכול לשלוח איתות Bluetooth, יש לצמצם את הבקשות כך שיהיו קבועות ולפעמים מיותרות, בלי להסתכן בהחמצת נתונים.

בעבר, מפתחים השתמשו באירועים של pagehide ו-visibilitychange כדי לקלוט את הדף תוך כדי הסרת הנתונים שנטענו, ולאחר מכן להשתמש ב-navigator.sendBeacon() או ב-fetch() עם keepalive כדי לשייך נתונים. עם זאת, בשני האירועים האלה יש מקרי פינה קשים שמשתנים בהתאם לדפדפן של המשתמש, ולפעמים האירועים לא מגיעים בכלל – במיוחד בנייד.

fetchLater() היא הצעה שתחליף את המורכבות הזו בקריאה אחת ל-API. היא פועלת בדיוק כפי שהשם שלה מרמז: היא מבקשת מהדפדפן לוודא שתתבצע בקשה בשלב כלשהו בעתיד, גם אם הדף נסגר או אם המשתמש מנווט למקום אחר.

הגרסה fetchLater() זמינה ב-Chrome לבדיקה עם משתמשים אמיתיים שעומדים בגרסת מקור לניסיון, החל מגרסה 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 ו-AbortController signal כדי לבטל אותה.

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

options

אובייקט האפשרויות מאריך את האפשרויות של fetch() עם זמן קצוב לתפוגה, activateAfter, למקרה שתרצה להפעיל את הבקשה לאחר הזמן הקצוב לתפוגה או כאשר הדף לא נטען, המוקדם מביניהם.

השיטה הזו מאפשרת לכם להחליט על איזון בין קבלת נתונים בזמן המוחלט האחרון או כשצריך לעשות זאת בזמן קצר יותר.

לדוגמה, אם יש לכם אפליקציה שהמשתמשים בדרך כלל משאירים פתוחה במשך כל יום העבודה, מומלץ להגדיר זמן קצוב לתפוגה של שעה, כדי לקבל ניתוח נתונים מפורט יותר ועדיין להבטיח איתות Bluetooth, גם אם המשתמש יצא בשלב כלשהו לפני שהזמן הקצוב פג. לאחר מכן אפשר יהיה להגדיר fetchLater() חדש עבור השעה הקרובה של ניתוח הנתונים.

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

שימוש לדוגמה

אחת הבעיות שמודדים בשדה מדדי ליבה לבדיקת חוויית המשתמש באתר היא שכל אחד ממדדי הביצועים עשוי להשתנות עד שהמשתמש יעזוב בפועל את הדף. לדוגמה, שינויים גדולים יותר בפריסה עשויים להתרחש בכל שלב, או שזמן התגובה של הדף לאינטראקציה עשוי להיות ארוך עוד יותר.

עם זאת, אינכם רוצים להסתכן באובדן כל נתוני הביצועים עקב דיווח על באגים או שגיאות חלקיות בהסרת הנתונים שנטענו בדף. זה מועמד מושלם לfetchLater().

בדוגמה הזו, הספרייה web-vitals.js משמשת למעקב אחר המדדים, ו-fetchLater() משמשת לדיווח על התוצאות לנקודת קצה של Analytics:

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() זמין בגרסת מקור לניסיון עד גרסה 126 של Chrome. מידע בסיסי על גרסאות המקור לניסיון זמין במאמר תחילת העבודה עם גרסאות מקור לניסיון

לצורך בדיקה מקומית, אפשר להפעיל את 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.

מידע נוסף