שיפור לסגירת דף ב-XMLHttpRequest() סינכרוני

ירידה בעיכובים בניווט

Joe Medley
Joe Medley

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

השיטה הזו צריכה להשתנות והדפדפנים מגיבים. המפרט של XMLHttpRequest() כבר מוכן להוצאה משימוש ולהסרה. בשלב הראשון, דפדפן Chrome 80 מונע קריאות סינכרוניות במספר גורמים מטפלים באירועים, באופן ספציפי ב-beforeunload, ב-unload, ב-pagehide וב-visibilitychange כשהם מופעלים בסגירה. ב-WebKit גם פורסם לאחרונה התחייבות להטמעת אותו שינוי התנהגות.

במאמר הזה אתאר בקצרה את האפשרויות למשתמשים שצריכים זמן כדי לעדכן את האתרים שלהם, ואפרט את החלופות ל-XMLHttpRequest().

ביטולי הסכמה זמניים

אנחנו לא רוצים להפסיק את השימוש ב-XMLHttpRequest(), ולכן יש כמה אפשרויות זמניות להפסקת השימוש. לאתרים באינטרנט, זמינה תקופת ניסיון במקור. כך מוסיפים לכותרות הדפים אסימון ספציפי למקור שמאפשר קריאות XMLHttpRequest() סינכרוניות. האפשרות הזו תסתיים זמן קצר לפני השקת Chrome 89, מתישהו במרץ 2021. לקוחות Chrome Enterprise יכולים גם להשתמש בדגל המדיניות AllowSyncXHRInPageDismissal, שייפסק באותו זמן.

אפשרויות אחרות

לא משנה איך שולחים נתונים חזרה לשרת, עדיף לא להמתין עד שהדף פורק כדי לשלוח את כל הנתונים בבת אחת. מלבד יצירה של חוויית משתמש גרועה, הסרת הנתונים שנטענו לא אמינה בדפדפנים מתקדמים, והיא מסתכנת באובדן נתונים אם משהו משתבש. באופן ספציפי, אירועי הסרה של נתונים שנטענו לרוב לא מופעלים בדפדפנים לנייד כי יש דרכים רבות לסגור כרטיסייה או דפדפן במערכות הפעלה לנייד בלי שהאירוע unload יופעל. ב-XMLHttpRequest(), השימוש במטענים ייעודיים (payloads) קטנים היה בחירה. עכשיו זה דרישה. שתי החלופות האלה כוללות מגבלה של 64 KB להעלאה לכל הקשר, כנדרש במפרט.

אחזור הודעת keep-alive

Fetch API מספק אמצעים יעילים להתמודדות עם אינטראקציות עם השרת וממשק עקבי לשימוש בממשקי API שונים של הפלטפורמה. אחת מהאפשרויות היא keepalive, שמבטיחה שהבקשה תמשיך גם אם הדף שהיא נשלחה ממנו נשאר פתוח וגם אם לא:

window.addEventListener('unload', {
  fetch('/siteAnalytics', {
    method: 'POST',
    body: getStatistics(),
    keepalive: true
  });
}

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

SendBeacon()‎

SendBeacon() למעשה משתמש ב-Fetch API באופן כללי, ולכן יש לו את אותה מגבלת מטען ייעודי (payload) של 64KB, ולכן הוא גם מבטיח שהבקשה תמשיך לאחר הסרת הדף. היתרון העיקרי שלו הוא הפשטות. הוא מאפשר לשלוח את הנתונים באמצעות שורת קוד אחת:

window.addEventListener('unload', {
  navigator.sendBeacon('/siteAnalytics', getStatistics());
}

סיכום

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

תמונה של Matthew Hamilton ב-Unsplash