שמירה על עדכניות בעזרת תכונות לא עדכניות תוך כדי אימות

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

stale-while-revalidate עוזר למפתחים לשמור על איזון בין מיידיות – טעינת תוכן ששמור במטמון באופן מיידי – לבין עדכניות – הבטחת שימוש בעדכונים של התוכן ששמור במטמון בעתיד. אם אתם מנהלים ספרייה או שירות אינטרנט של צד שלישי שמתעדכנים במתכונת קבועה, או שהנכסים מאינטראקציה ישירה (First-Party) שלכם נוטים להיות עם משך חיים קצר, יכול להיות ש-stale-while-revalidate הוא תוספת שימושית למדיניות האחסון במטמון הקיימת שלכם.

תמיכה בהגדרה של stale-while-revalidate לצד max-age בכותרת התשובה Cache-Control זמינה ב-Chrome 75 וב-Firefox 68.

דפדפנים שלא תומכים ב-stale-while-revalidate יתעלמו באופן עצמאי מערך ההגדרה הזה וישתמשו ב-max-age, כפי שאסביר בקרוב...

מה המשמעות של זה?

נחלק את stale-while-revalidate לשני חלקים: הרעיון שתגובה ששמורה במטמון עשויה להיות לא עדכנית, ותהליך האימות מחדש.

קודם כול, איך הדפדפן יודע אם תשובה ששמורה במטמון היא 'לא עדכנית'? כותרת התגובה Cache-Control שמכילה את stale-while-revalidate צריכה לכלול גם את max-age, ומספר השניות שצוין באמצעות max-age הוא זה שקובע את מידת הישנות. כל תגובה ששמורה במטמון אחרי max-age נחשבת חדשה, ותגובות ישנות יותר במטמון נחשבות ללא פעילות.

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

אבל אם התשובה ששמורה במטמון לא עדכנית, מתבצעת בדיקה נוספת לפי תאריך יצירה: האם התשובה ששמורה במטמון נמצאת בחלון הזמן הנוסף שצוין בהגדרה stale-while-revalidate?

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

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

דוגמה בזמן אמת

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

בתרחיש הזה, שרת האינטרנט משתמש בכותרת Cache-Control בתגובת ה-HTTP שלו:

Cache-Control: max-age=1, stale-while-revalidate=59

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

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

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

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

תרשים שממחיש את המידע מהקטע הקודם.

מהם התרחישים הנפוצים לדוגמה?

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

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

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

איך הוא מתקשר עם שירותי העבודה?

אם שמעתם על stale-while-revalidate, סביר להניח שזה היה בהקשר של מתכונים שמשמשים בסוכני שירות.

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

להשתמש בגישת Service Worker אם...

  • אתם כבר משתמשים בקובץ שירות (service worker) באפליקציית האינטרנט שלכם.
  • אתם צריכים שליטה מפורטת על התוכן של המטמון, ואתם רוצים להטמיע מדיניות תפוגה לפי 'שימוש הכי פחות עדכני'. מודול Cache Expiration של Workbox יכול לעזור לכם בכך.
  • אתם רוצים לקבל התראה כשתשובה לא עדכנית משתנה ברקע במהלך שלב אימות הנכונות מחדש. מודול Broadcast Cache Update של Workbox יכול לעזור לכם בכך.
  • צריך את ההתנהגות הזו של stale-while-revalidate בכל הדפדפנים המודרניים.

כדאי להשתמש בגישה של Cache-Control אם…

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

אם אתם משתמשים ב-service worker וגם הפעלתם את stale-while-revalidate בתשובות מסוימות באמצעות כותרת Cache-Control, בדרך כלל ל-service worker תהיה הזדמנות ראשונה להשיב לבקשה. אם עובד השירות יחליט לא להשיב, או אם בתהליך יצירת התגובה הוא ישלח בקשת רשת באמצעות fetch(), התנהגותו שתוגדר באמצעות הכותרת Cache-Control תהיה זו שתתבצע.

מידע נוסף

התמונה הראשית (Hero) של Samuel Zeller.