מה המפתחים צריכים לדעת על מצבי הזיכרון ומצב החיסכון באנרגיה של Chrome

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

המצבים החדשים האלה מיועדים בעיקר למשתמשים, אבל יש להם השלכות מסוימות שחשוב שמפתחי האתרים יהיו מודעים להן, כי הן עלולות להשפיע על חוויית המשתמש באתר.

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

מצב חיסכון בזיכרון

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

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

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

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

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

שיטות מומלצות לטיפול במחיקת כרטיסיות

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

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

הזמן הכי טוב לאחסן את מצב המשתמש הוא:

  • מדי פעם כשהמדינה משתנה.
  • כשכרטיסייה מועברת ברקע (האירוע visibilitychange).

הזמנים הגרועים ביותר לאחסון הם:

  • בקריאה חוזרת (callback) של אירוע beforeunload.
  • בקריאה חוזרת (callback) של אירוע unload.

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

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

המצב של ממשק ה-API של מחזור החיים של הדף וזרימת האירוע. ייצוג חזותי של המצב וזרימת האירוע שמתוארים במסמך הזה.

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

הקוד הבא מתאר לוגיקה לדוגמה של 'הבאים בתור' למצב המשתמש הנוכחי בכל פעם שהוא משתנה, או מיד אם המשתמש יוצא מרקע של הכרטיסייה או מנווט למקום אחר:

let state = {};
let hasUnstoredState = false;

function storeState() {
  if (hasUnstoredState) {
    // Store `state` to localStorage or IndexedDB...
  }
  hasUnstoredState = false;
}

export function updateState(newState) {
  state = newState;
  hasUnstoredState = true;
  requestIdleCallback(storeState);
}

document.addEventListener('visibilitychange', () => {
  if (document.visibilityState === 'hidden') {
    storeState();
  }
});

זיהוי שהכרטיסייה נמחקה

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

if (document.wasDiscarded) {
  // The page was reloaded after a discard.
} else {
  // The page was not reloaded after a discard.
}

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

לדוגמה, ב-Google Analytics אפשר להגדיר פרמטר מותאם אישית של אירוע, שיאפשר לכם לקבוע איזה אחוז של צפיות בדף הגיעו מתיקיות כרטיסיות:

gtag('config', 'G-XXXXXXXXXX', {
  was_discarded: document.wasDiscarded,
});

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

בדיקת האתר במצב חיסכון בזיכרון

כדי לבדוק איך דף מסוים מטפל במחיקה, אפשר לטעון את הדף ולהיכנס אל chrome://discards בכרטיסייה או בחלון נפרדים.

בממשק המשתמש של chrome://discards אפשר לאתר ברשימה את הכרטיסייה שרוצים למחוק ואז ללחוץ על מחיקה דחופה בעמודה פעולות.

צילום מסך של ממשק המשתמש של chrome://discards שמציג את מיקום הקישור למחיקת כרטיסיות

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

שימו לב שאין כרגע דרך להפוך בקשות מחיקה של כרטיסיות לאוטומטיות באמצעות כלי בדיקה כמו Webdriver או 'יצירת מבוכים'; עם זאת, מאחר שמחיקה ושחזור של כרטיסיות הן כמעט זהות לטעינות מחדש של דף, אם בודקים שמצב המשתמש ישוחזר לאחר טעינה מחדש באמצע תהליך של משתמש, סביר להניח שהוא יפתור גם מחיקה/שחזור. ההבדל העיקרי הוא שאירועי beforeunload, pagehide ו-unload לא מופעלים כשכרטיסייה נמחקת. לכן, כל עוד לא מסתמכים על האירועים האלה כדי לשמור על מצב המשתמש, אפשר להשתמש בטעינות מחדש כדי לבדוק את ההתנהגות של מחיקה/שחזור.

מצב חיסכון באנרגיה

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

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

התרחיש העיקרי שבו המצב הזה עלול להיות בעייתי הוא מצב שבו האתר משתמש באנימציות מבוססות JavaScript, שמתבססות על קצב רענון מסוים לכל המשתמשים.

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

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

מדידה של קצב הרענון ברשת המדיה

אין ממשק API ייעודי לאינטרנט כדי למדוד את קצב הרענון של התצוגה. באופן כללי, לא מומלץ לעשות זאת באמצעות ממשקי ה-API הקיימים.

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

בדיקת האתר במצב חיסכון באנרגיה

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

אם אין לך מכשיר שאפשר לנתק, ניתן גם להפעיל את המצב באופן ידני באופן הבא:

  1. הפעלת הדגל chrome://flags/#battery-saver-mode-available.
  2. עוברים אל chrome://discards ולוחצים על הקישור החלפת מצב חיסכון בסוללה (חשוב: כדי שהקישור יעבוד), צריך להפעיל את הדגל #battery-saver-mode-available.

צילום מסך של ממשק המשתמש chrome://discards שבו מוצג המיקום של הקישור להפעלת מצב חיסכון באנרגיה

לאחר ההפעלה, תוכלו לבצע פעולות באתר ולוודא שהכול נראה כמו שצריך: לדוגמה, שהאנימציות והמעברים פועלים במהירות הרצויה.

סיכום

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

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

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

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