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

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

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

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

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

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

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

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

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

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

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

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

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

הזמן הטוב ביותר לשמור את מצב המשתמש:

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

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

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

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

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

מצב ה-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 יהיה TRUE.

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 שמציג את מיקום הקישור למחיקת כרטיסיות

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

שים לב: בשלב זה אין דרך להפוך מחיקת כרטיסיות לאוטומטיות באמצעות כלי בדיקה כמו נהג אינטרנט או puppeteer; עם זאת, המחיקה והשחזור של כרטיסיות הן כמעט זהות לטעינות מחדש של דפים, אם אתה בודק שמצב המשתמש ישוחזר לאחר טעינה מחדש באמצע תהליך המשתמש, סביר להניח שהוא יפעל גם למחיקה/לשחזור. ההבדל העיקרי בין השניים הוא האירועים 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 הם פיצ'רים גלויים למשתמשים, אבל יש להם השלכות על המפתחים, כי אם לא תטפלו בהם בצורה נכונה, תהיה להם השלכות שליליות על חוויית הביקור באתר.

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

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

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