תאריך פרסום: 25 במאי 2023, תאריך עדכון אחרון: 25 במרץ 2025
התכונה 'מטמון לדף הקודם/הבא' (או bfcache) היא אופטימיזציה של דפדפן שמאפשרת ניווט מיידי אחורה וקדימה. היא משפרת משמעותית את חוויית השימוש בדפדפן, במיוחד למשתמשים שהרשתות או המכשירים שלהם איטיים יותר.
מפתחי אתרים צריכים להבין איך מבצעים אופטימיזציה של הדפים לשימוש במטמון אחורה/קדימה, כדי שהמשתמשים יוכלו ליהנות מהיתרונות שלו.
תאימות דפדפן
כל הדפדפנים הנפוצים כוללים bfcache, כולל Chrome מגרסה 96, Firefox ו-Safari.
מידע בסיסי על bfcache
במקום להרוס דף כשמשתמש מנווט ממנו, אנחנו דוחים את ההרס ומשהים את ביצוע ה-JS באמצעות מטמון לדף הקודם/הבא (bfcache). אם המשתמש חוזר לדף במהירות, אנחנו הופכים את הדף לגלוי שוב ומבטלים את ההשהיה של הרצת ה-JS. כך המשתמש יכול לנווט בין הדפים כמעט באופן מיידי.
כמה פעמים קרה לכם שנכנסתם לאתר מסוים ולחצתם על קישור כדי לעבור לדף אחר, ואז הבנתם שזה לא מה שרציתם ולחצתם על הכפתור "הקודם"? במקרה כזה, המטמון לדף הקודם/הבא יכול לשפר משמעותית את מהירות הטעינה של הדף הקודם:
| ללא bfcache | מתחילה בקשה חדשה לטעינת הדף הקודם, ותלוי באיכות האופטימיזציה של הדף לביקורים חוזרים, יכול להיות שהדפדפן יצטרך להוריד מחדש, לנתח מחדש ולהפעיל מחדש חלק מהמשאבים שהוא הוריד זה עתה (או את כולם). |
| עם bfcache מופעל | טעינת הדף הקודם היא כמעט מיידית, כי אפשר לשחזר את כל הדף מהזיכרון, בלי להיכנס לרשת בכלל. |
כדי להבין איך התכונה הזו יכולה לזרז את הניווטים, כדאי לצפות בסרטון הזה שמציג את המטמון לדף הקודם/הבא בפעולה:
בדוגמה בסרטון, המטמון bfcache מהיר משמעותית מהדוגמה בלי המטמון.
ה-bfcache לא רק מזרז את הניווט, אלא גם מצמצם את השימוש בחבילת הגלישה, כי לא צריך להוריד שוב את המשאבים.
נתוני השימוש ב-Chrome מראים ש-1 מתוך 10 ניווטים במחשב ו-1 מתוך 5 בנייד הם ניווטים אחורה או קדימה. אם bfcache מופעל, דפדפנים יכולים למנוע את העברת הנתונים ואת הזמן שנדרש לטעינה של מיליארדי דפי אינטרנט בכל יום!
איך פועל המטמון
המטמון שבו נעשה שימוש ב-bfcache שונה ממטמון ה-HTTP, שגם לו יש תפקיד בזירוז הניווטים החוזרים. מטמון ה-bfcache הוא תמונת מצב של הדף כולו בזיכרון, כולל ערימת ה-JavaScript, בעוד שמטמון ה-HTTP מכיל רק את התשובות לבקשות שבוצעו בעבר. מאחר שמאוד נדיר שכל הבקשות שנדרשות לטעינת דף יסופקו מהמטמון של HTTP, ביקורים חוזרים באמצעות שחזורים של מטמון לדף הקודם/הבא תמיד מהירים יותר אפילו מהניווטים הכי מותאמים שלא משתמשים במטמון לדף הקודם/הבא.
הקפאת דף כדי להפעיל אותו מחדש בהמשך היא תהליך מורכב שדורש שימור של קוד שנמצא בתהליך. לדוגמה, איך מטפלים בשיחות setTimeout() שבהן הגיע הזמן הקצוב לתפוגה בזמן שהדף נמצא במטמון bfcache?
התשובה היא שהדפדפנים משהים את כל הטיימרים שממתינים או את ההבטחות שלא נפתרו בדפים במטמון bfcache, כולל כמעט כל המשימות שממתינות בתורי המשימות של JavaScript, וממשיכים לעבד את המשימות אם הדף משוחזר מהמטמון bfcache.
במקרים מסוימים, כמו פסק זמן והבטחות, הסיכון נמוך יחסית, אבל במקרים אחרים זה עלול להוביל להתנהגות מבלבלת או לא צפויה. לדוגמה, אם הדפדפן משהה משימה שנדרשת כחלק מטרנזקציה של IndexedDB, זה יכול להשפיע על כרטיסיות פתוחות אחרות באותו מקור, כי אפשר לגשת למסדי נתונים של IndexedDB מכמה כרטיסיות בו-זמנית. כתוצאה מכך, בדרך כלל הדפדפנים לא ינסו לשמור במטמון דפים באמצע טרנזקציה של IndexedDB או בזמן שימוש בממשקי API שעשויים להשפיע על דפים אחרים.
פרטים נוספים על האופן שבו השימוש ב-API משפיע על ההתאמה של דף ל-bfcache זמינים במאמר אופטימיזציה של דפים ל-bfcache.
המטמון bfcache ומסגרות iframe
אם דף מכיל מסגרות iframe מוטמעות, המסגרות האלה לא מתאימות לשמירה במטמון לדף הקודם/הבא בנפרד. לדוגמה, אם עוברים לכתובת URL אחרת בתוך iframe, התוכן הקודם לא נכנס ל-bfcache, ואם חוזרים אחורה, הדפדפן יחזור אחורה בתוך ה-iframe ולא בפריים הראשי, אבל הניווט אחורה בתוך ה-iframe לא ישתמש ב-bfcache.
עם זאת, כשמשחזרים את המסגרת הראשית מהמטמון לדף הקודם/הבא, משחזרים גם את ה-iframe המוטמעים כמו שהם היו כשהדף נכנס למטמון לדף הקודם/הבא.
יכול להיות שגם המסגרת הראשית תיחסם משימוש ב-bfcache אם נעשה שימוש ב-iframe מוטמע בממשקי API שחוסמים את השימוש הזה. כדי למנוע את הבעיה הזו, אפשר להשתמש במדיניות ההרשאות שמוגדרת בפריים הראשי או במאפייני sandbox.
מטמון הדפדפן (bfcache) ואפליקציות בדף יחיד (SPA)
מכיוון שה-bfcache פועל עם ניווטים שמנוהלים על ידי הדפדפן, הוא לא פועל עם 'ניווטים רכים' באפליקציה של דף יחיד (SPA). עם זאת, bfcache עדיין יכול לעזור כשחוזרים ל-SPA במקום לבצע שוב אתחול מלא של האפליקציה מההתחלה.
ממשקי API לצפייה ב-bfcache
למרות שמטמון bfcache הוא אופטימיזציה שהדפדפנים מבצעים באופן אוטומטי, עדיין חשוב למפתחים לדעת מתי זה קורה כדי שהם יוכלו לבצע אופטימיזציה של הדפים שלהם ולשנות את המדדים או את מדידת הביצועים בהתאם.
האירועים העיקריים שמשמשים למעקב אחרי bfcache הם אירועי מעבר בין דפים pageshow ו-pagehide, שנתמכים על ידי רוב הדפדפנים.
גם האירועים החדשים יותר של מחזור החיים של הדף – freeze ו-resume – נשלחים כשדפים נכנסים ל-bfcache או יוצאים ממנו, וגם במצבים אחרים, למשל כשכרטיסייה ברקע קופאת כדי לצמצם את השימוש במעבד. האירועים האלה נתמכים רק בדפדפנים שמבוססים על Chromium.
איך יודעים מתי דף משוחזר מ-bfcache
האירוע pageshow מופעל מיד אחרי האירוע load כשהדף נטען בפעם הראשונה, ובכל פעם שהדף משוחזר מהמטמון לדף הקודם/הבא. לאירוע pageshow יש מאפיין persisted, שהערך שלו הוא true אם הדף שוחזר מהמטמון לדף הקודם/הבא, ו-false בכל מקרה אחר. אפשר להשתמש במאפיין persisted כדי להבחין בין טעינות רגילות של דפים לבין שחזורים של bfcache. לדוגמה:
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
console.log('This page was restored from the bfcache.');
} else {
console.log('This page was loaded normally.');
}
});
בדפדפנים שתומכים ב-Page Lifecycle API, האירוע resume מופעל כשדפים משוחזרים מ-bfcache (מטמון אחורי/קדמי) (מיד לפני האירוע pageshow) וכשמשתמש חוזר לכרטיסיית רקע קפואה. אם רוצים לעדכן את מצב הדף אחרי שהוא קופא (כולל דפים במטמון bfcache), אפשר להשתמש באירוע resume, אבל אם רוצים למדוד את שיעור הפגיעה במטמון bfcache של האתר, צריך להשתמש באירוע pageshow. במקרים מסוימים, יכול להיות שתצטרכו להשתמש בשניהם.
פרטים על שיטות מומלצות למדידת bfcache זמינים במאמר איך bfcache משפיע על ניתוח נתונים ומדידת ביצועים.
מעקב אחרי הכניסה של דף למטמון bfcache
האירוע pagehide מופעל כשהדף מוסר מהזיכרון או כשהדפדפן מנסה להכניס אותו ל-bfcache.
לאירוע pagehide יש גם מאפיין persisted. אם הערך הוא false, אפשר להיות בטוחים שהדף לא ייכנס למטמון לדף הקודם/הבא. עם זאת, persistedהיותו של דף true לא מבטיח שהוא יישמר במטמון. המשמעות היא שהדפדפן מתכוון לשמור את הדף במטמון, אבל יכול להיות שיש גורמים אחרים שלא מאפשרים לשמור אותו במטמון.
window.addEventListener('pagehide', (event) => {
if (event.persisted) {
console.log('This page *might* be entering the bfcache.');
} else {
console.log('This page will unload normally and be discarded.');
}
});
באופן דומה, האירוע freeze מופעל מיד אחרי האירוע pagehide אם הערך של persisted הוא true, אבל זה רק אומר שהדפדפן מתכוון לשמור את הדף במטמון. יכול להיות שהמערכת עדיין תצטרך להסיר אותו מכמה סיבות שמוסברות בהמשך.
אופטימיזציה של הדפים ל-bfcache
לא כל הדפים נשמרים ב-bfcache, וגם אם דף נשמר שם, הוא לא יישאר שם לנצח. חשוב מאוד שמפתחים יבינו מה הופך דפים לכשירים (או לא כשירים) לשימוש ב-bfcache, כדי למקסם את שיעורי הפגיעה במטמון.
בקטעים הבאים מפורטות שיטות מומלצות שיעזרו לכם להגדיל את הסיכוי שהדפדפן יוכל לשמור את הדפים שלכם במטמון.
לעולם לא להשתמש באירוע unload
הדרך הכי חשובה לבצע אופטימיזציה ל-bfcache בכל הדפדפנים היא לא להשתמש אף פעם באירוע unload. אף פעם!
האירוע unload בעייתי לדפדפנים כי הוא קדם ל-bfcache, והרבה דפים באינטרנט פועלים מתוך הנחה (סבירה) שדף לא ימשיך להתקיים אחרי שהאירוע unload יופעל. זו בעיה כי הרבה מהדפים האלה נבנו גם מתוך הנחה שהאירוע unload יופעל בכל פעם שמשתמש עובר לדף אחר, אבל זה כבר לא נכון (ולא היה נכון במשך הרבה זמן).
לכן, הדפדפנים מתמודדים עם דילמה: הם צריכים לבחור בין שיפור חוויית המשתמש לבין סיכון של פגיעה בדף.
במחשב, דפדפני Chrome ו-Firefox בוחרים להוציא דפים משימוש במטמון bfcache אם הם מוסיפים מאזין unload, מה שמפחית את הסיכון אבל גם פוסל הרבה דפים. דפדפן Safari ינסה לשמור במטמון חלק מהדפים עם מאזין אירועים מסוג unload, אבל כדי לצמצם את הסיכון לבעיות, הוא לא יפעיל את ה-event listener unload כשמשתמש עובר לדף אחר. לכן, אי אפשר להסתמך על האירוע הזה.
בנייד, דפדפני Chrome ו-Safari ינסו לשמור במטמון דפים עם מאזין לאירוע unload, כי הסיכון לשבירה נמוך יותר בגלל העובדה שהאירוע unload תמיד היה לא אמין במיוחד בנייד. דפדפן Firefox לא מאפשר לשמור במטמון לדף הקודם/הבא דפים שנעשה בהם שימוש ב-unload, למעט ב-iOS. ב-iOS כל הדפדפנים צריכים להשתמש במנוע העיבוד WebKit, ולכן הוא מתנהג כמו Safari.
במקום להשתמש באירוע unload, צריך להשתמש באירוע pagehide. האירוע pagehide מופעל בכל המקרים שבהם מופעל האירוע unload, וגם כשהדף מוכנס למטמון bfcache.
למעשה, ב-Lighthouse יש ביקורת no-unload-listeners, שמזהירה מפתחים אם קוד JavaScript בדפים שלהם (כולל קוד מספריות של צד שלישי) מוסיף event listener מסוג unload.
בגלל חוסר המהימנות של האירוע הזה וההשפעה שלו על הביצועים של bfcache, אנחנו ב-Chrome מתכננים להוציא משימוש את האירוע .unload
שימוש במדיניות הרשאות כדי למנוע שימוש ב-unload handlers בדף
אתרים שלא משתמשים ב-handlers של אירועים מסוג unload יכולים להשתמש במדיניות הרשאות כדי לוודא שהם לא יתווספו.
Permissions-Policy: unload=()
בנוסף, כך נמנעים מצבים שבהם צדדים שלישיים או תוספים מאטים את האתר על ידי הוספת handlers של הסרת טעינה, ומונעים מהאתר להיות כשיר לשימוש ב-bfcache.
הוספת beforeunload מאזינים רק בתנאי
האירוע beforeunload לא יגרום לכך שהדפים שלכם לא יעמדו בדרישות לשימוש ב-bfcache ב-bfcache של דפדפנים מודרניים, אבל בעבר הוא גרם לכך, והוא עדיין לא אמין, לכן מומלץ להימנע משימוש בו אלא אם הדבר נחוץ לחלוטין.
עם זאת, בניגוד לאירוע unload, יש שימושים לגיטימיים ב-beforeunload. לדוגמה, כשרוצים להזהיר את המשתמש שיש לו שינויים שלא נשמרו והוא יאבד אותם אם הוא ייצא מהדף. במקרה כזה, מומלץ להוסיף רק מאזינים של beforeunload כשמשתמש מבצע שינויים שלא נשמרו, ואז להסיר אותם מיד אחרי שהשינויים נשמרים.
window.addEventListener('beforeunload', (event) => { if (pageHasUnsavedChanges()) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; } });
beforeunload ללא תנאי.
function beforeUnloadListener(event) { event.preventDefault(); return event.returnValue = 'Are you sure you want to exit?'; }; // A function that invokes a callback when the page has unsaved changes. onPageHasUnsavedChanges(() => { window.addEventListener('beforeunload', beforeUnloadListener); }); // A function that invokes a callback when the page's unsaved changes are resolved. onAllChangesSaved(() => { window.removeEventListener('beforeunload', beforeUnloadListener); });
beforeunload רק כשצריך (ומסיר אותו כשלא צריך).
צמצום השימוש ב-Cache-Control: no-store
Cache-Control: no-store היא כותרת HTTP ששרתי אינטרנט יכולים להגדיר בתגובות, כדי להנחות את הדפדפן לא לאחסן את התגובה בשום מטמון HTTP. הוא משמש למשאבים שמכילים מידע רגיש על משתמשים, כמו דפים שנדרשת התחברות כדי לגשת אליהם.
למרות שמטמון לדף הקודם/הבא הוא לא מטמון HTTP, בעבר, כשערך הכותרת Cache-Control: no-store הוגדר במשאב הדף עצמו (ולא במשאב משני), הדפדפנים בחרו לא לשמור את הדף במטמון לדף הקודם/הבא, ולכן יכול להיות שדפים שנעשה בהם שימוש ב-Cache-Control: no-store לא יעמדו בדרישות לשמירה במטמון לדף הקודם/הבא. אנחנו עובדים על שינוי ההתנהגות הזו ב-Chrome באופן ששומר על הפרטיות.
המאפיין Cache-Control: no-store מגביל את הזכאות של דף לשימוש במטמון לדף הקודם/הבא, ולכן צריך להגדיר אותו רק בדפים שמכילים מידע רגיש, שבהם אף פעם לא מתאים להשתמש במטמון מכל סוג שהוא.
בדפים שצריך להציג בהם תמיד תוכן עדכני, ושלא מכילים מידע רגיש, אפשר להשתמש ב-Cache-Control: no-cache או ב-Cache-Control: max-age=0. ההוראות האלה מנחות את הדפדפן לאמת מחדש את התוכן לפני שהוא מוצג, והן לא משפיעות על הזכאות של דף לשימוש במטמון אחורה/קדימה.
שימו לב שכאשר דף משוחזר מהמטמון לדף הקודם/הבא, הוא משוחזר מהזיכרון ולא ממטמון ה-HTTP. כתוצאה מכך, הנחיות כמו Cache-Control: no-cache או Cache-Control: max-age=0 לא נלקחות בחשבון, ולא מתבצעת אימות מחדש לפני שהתוכן מוצג למשתמש.
עם זאת, סביר להניח שזו עדיין חוויית משתמש טובה יותר, כי השחזורים של bfcache הם מיידיים, והדפים לא נשארים ב-bfcache למשך זמן רב מדי, כך שסביר להניח שהתוכן עדיין עדכני. עם זאת, אם התוכן משתנה מדי דקה, אפשר לאחזר עדכונים באמצעות האירוע pageshow, כפי שמתואר בקטע הבא.
עדכון נתונים ישנים או מידע אישי רגיש אחרי שחזור מ-bfcache
אם האתר שלכם שומר את מצב המשתמש – במיוחד מידע רגיש כלשהו על המשתמש – צריך לעדכן או לנקות את הנתונים האלה אחרי שדף משוחזר מ-bfcache.
לדוגמה, אם משתמש מנווט לדף תשלום ואז מעדכן את עגלת הקניות שלו, ניווט אחורה עלול לחשוף מידע לא עדכני אם דף ישן משוחזר מ-bfcache.
דוגמה נוספת, קריטית יותר, היא אם משתמש מתנתק מאתר במחשב ציבורי והמשתמש הבא לוחץ על הכפתור "הקודם". כך עלולים להיחשף נתונים פרטיים שהמשתמש חשב שנמחקו כשהוא יצא מהחשבון.
כדי למנוע מצבים כאלה, מומלץ לעדכן תמיד את הדף אחרי אירוע pageshow אם event.persisted הוא true:
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// Do any checks and updates to the page
}
});
מומלץ לעדכן את התוכן במקום, אבל לפעמים כדאי לבצע טעינה מחדש מלאה. הקוד הבא בודק אם יש קובץ Cookie ספציפי לאתר באירוע pageshow, וטוען מחדש אם קובץ ה-Cookie לא נמצא:
window.addEventListener('pageshow', (event) => {
if (event.persisted && !document.cookie.match(/my-cookie)) {
// Force a reload if the user has logged out.
location.reload();
}
});
יתרון של טעינה מחדש הוא שההיסטוריה נשמרת (כדי לאפשר ניווט קדימה), אבל במקרים מסוימים הפניה אוטומטית עשויה להתאים יותר.
מודעות ושחזור מ-bfcache
יכול להיות שתתפתו לנסות להימנע משימוש ב-bfcache כדי להציג קבוצה חדשה של מודעות בכל ניווט לחזרה או קדימה. עם זאת, בנוסף להשפעה על הביצועים, לא ברור אם התנהגות כזו מובילה לאינטראקציה טובה יותר עם מודעה. יכול להיות שמשתמשים ראו מודעה שהם רצו לחזור אליה כדי ללחוץ עליה, אבל אם הם טענו מחדש את הדף במקום לשחזר אותו ממטמון הדפדפן (bfcache), הם לא יוכלו לעשות זאת. חשוב לבדוק את התרחיש הזה – רצוי באמצעות בדיקת A/B – לפני שמניחים הנחות.
באתרים שבהם רוצים לרענן את המודעות כשמתבצע שחזור מ-bfcache, אפשר לרענן רק את המודעות באירוע pageshow כש-event.persisted הוא true, וכך לא להשפיע על ביצועי הדף. כדאי לבדוק את זה מול ספק המודעות, אבל הנה דוגמה אחת לאופן שבו עושים את זה באמצעות Google Publisher Tag.
הימנעות מהפניות ל-window.opener
בדפדפנים ישנים יותר, אם דף נפתח באמצעות window.open() מקישור עם target=_blank, בלי לציין rel="noopener", לדף הפותח תהיה הפניה לאובייקט החלון של הדף שנפתח.
בנוסף לסיכון האבטחה, אי אפשר להכניס בבטחה דף עם הפניה window.opener שאינה null למטמון bfcache, כי זה עלול לשבור דפים שמנסים לגשת אליו.
לכן, מומלץ להימנע מיצירת הפניות ל-window.opener. אפשר לעשות את זה באמצעות rel="noopener" בכל הזדמנות (שימו לב, זו עכשיו ברירת המחדל בכל הדפדפנים המודרניים). אם האתר שלכם דורש פתיחת חלון ושליטה בו באמצעות window.postMessage() או הפניה ישירה לאובייקט החלון, החלון שנפתח והחלון שפתח אותו לא יעמדו בדרישות לשימוש במטמון הדפדפן.
סגירת חיבורים פתוחים לפני שהמשתמש עובר לדף אחר
כמו שצוין קודם, כשדף נשמר במטמון לדף הקודם/הבא, כל משימות ה-JavaScript המתוזמנות מושהות ומתחדשות כשהדף מוצא מהמטמון.
אם משימות ה-JavaScript המתוזמנות האלה ניגשות רק לממשקי DOM API – או לממשקי API אחרים שמבודדים רק לדף הנוכחי – השהיית המשימות האלה בזמן שהדף לא גלוי למשתמש לא תגרום לבעיות.
עם זאת, אם המשימות האלה מקושרות לממשקי API שנגישים גם מדפים אחרים באותו מקור (לדוגמה: IndexedDB, Web Locks, WebSockets), זה עלול להיות בעייתי כי השהיית המשימות האלה עלולה למנוע את הפעלת הקוד בכרטיסיות אחרות.
כתוצאה מכך, חלק מהדפדפנים לא ינסו להכניס דף ל-bfcache בתרחישים הבאים:
- דפים עם חיבור IndexedDB פתוח
- דפים עם fetch() או XMLHttpRequest בתהליך
- דפים עם חיבור פתוח של WebSocket או WebRTC
אם הדף שלכם משתמש באחד מה-API האלה, מומלץ מאוד לסגור את החיבורים ולהסיר או לנתק את האובייקטים של Observer במהלך האירוע pagehide או freeze. כך הדפדפן יכול לשמור את הדף במטמון בצורה בטוחה בלי להשפיע על כרטיסיות פתוחות אחרות.
לאחר מכן, אם הדף משוחזר מה-bfcache, אפשר לפתוח מחדש את ממשקי ה-API האלה או להתחבר אליהם מחדש במהלך האירוע pageshow או resume.
בדוגמה הבאה אפשר לראות איך לוודא שדפים שמשתמשים ב-IndexedDB עומדים בדרישות לשימוש ב-bfcache. לשם כך, סוגרים חיבור פתוח ב-event listener pagehide:
let dbPromise;
function openDB() {
if (!dbPromise) {
dbPromise = new Promise((resolve, reject) => {
const req = indexedDB.open('my-db', 1);
req.onupgradeneeded = () => req.result.createObjectStore('keyval');
req.onerror = () => reject(req.error);
req.onsuccess = () => resolve(req.result);
});
}
return dbPromise;
}
// Close the connection to the database when the user leaves.
window.addEventListener('pagehide', () => {
if (dbPromise) {
dbPromise.then(db => db.close());
dbPromise = null;
}
});
// Open the connection when the page is loaded or restored from bfcache.
window.addEventListener('pageshow', () => openDB());
בדיקה כדי לוודא שאפשר לשמור את הדפים במטמון
כלי הפיתוח ל-Chrome יכולים לעזור לכם לבדוק את הדפים כדי לוודא שהם מותאמים ל-bfcache, ולזהות בעיות שעשויות למנוע את ההתאמה שלהם.
כדי לבדוק דף:
- עוברים לדף ב-Chrome.
- בכלי הפיתוח, עוברים אל Application (אפליקציה) -> Back-forward Cache (מטמון של דפי חזרה ודפי מעבר).
- לוחצים על הלחצן הפעלת הבדיקה. לאחר מכן, כלי הפיתוח מנסים לנווט החוצה מהדף ואז לחזור אליו כדי לקבוע אם אפשר לשחזר את הדף ממטמון bfcache.
אם הבדיקה מצליחה, בחלונית מופיעה ההודעה 'שוחזר מתוך מטמון לדף הקודם/הבא'.
אם הפעולה לא מצליחה, בלוח מופיעה הסיבה לכך. אם הסיבה היא משהו שאתם יכולים לטפל בו כמפתחים, החלונית תסמן אותה כניתנת לביצוע.
בדוגמה הזו, השימוש ב-event listener unload גורם לכך שהדף לא עומד בדרישות לשמירה במטמון לדף הקודם/הבא. כדי לפתור את הבעיה, צריך לעבור משימוש ב-unload לשימוש ב-pagehide:
window.addEventListener('pagehide', ...);
window.addEventListener('unload', ...);
ב-Lighthouse 10.0 נוספה גם בדיקה של bfcache, שמבצעת בדיקה דומה. מידע נוסף זמין במסמכי התיעוד בנושא ביקורת של מטמון הדפדפן.
איך מטמון bfcache משפיע על ניתוח נתונים ומדידת ביצועים
אם אתם משתמשים בכלי ניתוח כדי למדוד את הביקורים באתר, יכול להיות שתבחינו בירידה במספר הכולל של הצפיות בדף שמדווחות כש-Chrome מפעיל את bfcache ליותר משתמשים.
למעשה, סביר להניח שאתם כבר מדווחים על מספר נמוך מדי של צפיות בדפים מדפדפנים אחרים שמטמיעים bfcache, כי הרבה ספריות פופולריות של ניתוח נתונים לא מודדות שחזורים של bfcache כצפיות חדשות בדפים.
כדי לכלול שחזורים של bfcache בספירת הצפיות בדף, צריך להגדיר מאזינים לאירוע pageshow ולבדוק את המאפיין persisted.
בדוגמה הבאה אפשר לראות איך עושים את זה באמצעות Google Analytics. בכלים אחרים לניתוח נתונים כנראה נעשה שימוש בלוגיקה דומה:
// Send a pageview when the page is first loaded.
// This happens by default just by loading gtag
gtag('config', 'TAG_ID');
window.addEventListener('pageshow', (event) => {
// Send another pageview if the page is restored from bfcache.
if (event.persisted) {
gtag('event', 'page_view');
}
});
מדידת יחס ההצלחה של bfcache
כדאי גם למדוד אם נעשה שימוש ב-bfcache, כדי לזהות דפים שלא נעשה בהם שימוש ב-bfcache. כדי לעשות את זה, אפשר למדוד את סוג הניווט בטעינות הדף:
// Send a navigation_type when the page is first loaded.
// To do this disable the default pageview so you can manually send it
// supplemented with the additional detail.
gtag('config', 'TAG_ID', { send_page_view: false });
gtag('event', 'page_view', {
'navigation_type': performance.getEntriesByType('navigation')[0].type;
});
window.addEventListener('pageshow', (event) => {
if (event.persisted) {
// Send another pageview if the page is restored from bfcache.
gtag('event', 'page_view', {
'navigation_type': 'back_forward_cache';
});
}
});
כדי לחשב את שיעור הפגיעה ב-bfcache, משתמשים בערכים של back_forward ניווטים וback_forward_cache ניווטים.
חשוב להבין שיש מספר תרחישים, שלא נמצאים בשליטת בעלי האתרים, שבהם לא נעשה שימוש במטמון לדפדפוף אחורה או קדימה, כולל:
- כשהמשתמש יוצא מהדפדפן ומתחיל אותו מחדש
- כשהמשתמש משכפל כרטיסייה
- כשמשתמש סוגר כרטיסייה ופותח אותה מחדש
בחלק מהמקרים האלה, דפדפנים מסוימים עשויים לשמור על סוג הניווט המקורי, ולכן עשויים להציג סוג של back_forward למרות שאלה לא ניווטים מסוג 'הקודם' או 'הבא'.
גם בלי ההחרגות האלה, מטמון הדפדפן יימחק אחרי תקופה מסוימת כדי לחסוך בזיכרון.
לכן, בעלי אתרים לא צריכים לצפות ליחס פגיעה של 100% במטמון הדפדפן לכל back_forward ניווט. עם זאת, מדידת היחס הזה יכולה לעזור לזהות דפים שבהם הדף עצמו מונע שימוש ב-bfcache עבור שיעור גבוה של ניווטים אחורה וקדימה.
צוות Chrome הוסיף את NotRestoredReasons API כדי לחשוף את הסיבות לכך שדפים לא משתמשים במטמון bfcache, וכך לעזור למפתחים לשפר את שיעורי ההצלחה של bfcache. צוות Chrome גם הוסיף סוגי ניווט ל-CrUX, כך שאפשר לראות את מספר הניווטים ב-bfcache גם בלי למדוד אותו בעצמכם.
מדידת ביצועים
בנוסף, מטמון bfcache יכול להשפיע באופן שלילי על מדדי הביצועים שנאספים בשטח, במיוחד על מדדים שמודדים את זמני הטעינה של הדף.
ניווטים באמצעות bfcache משחזרים דף קיים במקום ליזום טעינה של דף חדש, ולכן המספר הכולל של טעינות הדפים שייאספו יקטן כשמפעילים את bfcache. עם זאת, חשוב לזכור שטעינות הדפים שמוחלפות בשחזורים ממטמון הדפדפן היו כנראה חלק מטעינות הדפים המהירות ביותר במערך הנתונים שלכם. הסיבה לכך היא שהניווט לדף הקודם ולדף הבא הוא, מעצם הגדרתו, ביקור חוזר, וטעינות חוזרות של דפים הן בדרך כלל מהירות יותר מטעינות של דפים על ידי מבקרים חדשים (בגלל שמירה במטמון של HTTP, כמו שצוין קודם).
התוצאה היא פחות טעינות מהירות של דפים במערך הנתונים, ולכן סביר להניח שהחלוקה תהיה איטית יותר – למרות שהביצועים שהמשתמש חווה כנראה השתפרו!
יש כמה דרכים לפתור את הבעיה הזו. אחת מהן היא להוסיף הערה לכל מדדי טעינת הדף עם סוג הניווט המתאים: navigate, reload, back_forward או prerender. כך תוכלו להמשיך לעקוב אחרי הביצועים שלכם בסוגי הניווט האלה, גם אם החלוקה הכוללת מוטה לכיוון שלילי. אנחנו ממליצים על הגישה הזו למדדים של טעינת דפים שלא מתמקדים במשתמש, כמו הזמן עד הבייט הראשון (TTFB).
במקרה של מדדים שמתמקדים במשתמשים, כמו Core Web Vitals, עדיף לדווח על ערך שמייצג בצורה מדויקת יותר את חוויית המשתמש.
ההשפעה על Core Web Vitals
Core Web Vitals מודדים את חוויית המשתמש בדף אינטרנט במגוון היבטים (מהירות טעינה, אינטראקטיביות, יציבות חזותית). מכיוון שהמשתמשים חווים שחזורים ממטמון bfcache הם מהירים יותר מטעינות מלאות של דפים, חשוב שהמדדים של Core Web Vitals ישקפו זאת. בסופו של דבר, למשתמש לא משנה אם התכונה bfcache הופעלה או לא, אלא רק שהניווט היה מהיר.
כלים שאוספים נתונים על Core Web Vitals ומדווחים עליהם, כמו דוח על חוויית המשתמש ב-Chrome (CrUX), מתייחסים לשחזורים של bfcache כאל כניסות נפרדות לדף במערך הנתונים שלהם. אין ממשקי API ייעודיים לביצועי אתרים למדידת המדדים האלה אחרי שחזור מ-bfcache, אבל אפשר להעריך את הערכים שלהם באמצעות ממשקי API קיימים לאינטרנט:
- במקרה של Largest Contentful Paint (LCP), משתמשים בדלתא בין חותמת הזמן של האירוע
pageshowלבין חותמת הזמן של המסגרת הבאה שצוירה, כי כל הרכיבים במסגרת יצויירו בו-זמנית. במקרה של שחזור מ-bfcache, הערכים של LCP ו-FCP זהים. - לגבי מהירות התגובה לאינטראקציה באתר (INP), ממשיכים להשתמש ב-Performance Observer הקיים, אבל מאפסים את הערך הנוכחי של INP ל-0.
- לגבי מדד יציבות חזותית (CLS), צריך להמשיך להשתמש ב-Performance Observer הקיים, אבל לאפס את ערך ה-CLS הנוכחי ל-0.
פרטים נוספים על ההשפעה של מטמון bfcache על כל מדד זמינים בדפי המדריכים של כל אחד ממדדי ה-Core Web Vitals. דוגמה ספציפית להטמעה של גרסאות bfcache של המדדים האלה מופיעה בבקשת המשיכה (PR) להוספת המדדים האלה לספריית web-vitals JS.
ספריית JavaScript web-vitals תומכת בשחזורים של bfcache במדדים שהיא מדווחת עליהם.
מקורות מידע נוספים
- Firefox Caching (bfcache in Firefox)
- Page Cache (bfcache in Safari)
- Back/forward cache: web exposed behavior (bfcache differences across browsers)
- bfcache tester (test how different APIs and events affect bfcache in browsers)
- Performance Game Changer: Browser Back/Forward Cache (מקרה לדוגמה מ-Smashing Magazine שמציג שיפורים משמעותיים ב-Core Web Vitals בעקבות הפעלת bfcache)