משתמשים שיטעמו את האתר בפעם השנייה ישתמשו במטמון ה-HTTP שלהם, לכן חשוב לוודא שהוא פועל בצורה תקינה.
הפוסט הזה הוא כתבה נלווית לסרטון Love your cache, שחלק מהתוכן המורחב בכנס Chrome Dev Summit 2020. מומלץ לצפות בסרטון:
כשמשתמשים יטענו את האתר בפעם השנייה, הדפדפן שלהם ישתמש במשאבים שבמטמון ה-HTTP שלו כדי לזרז את הטעינה. אבל הסטנדרטים לשמירת קבצים במטמון באינטרנט מתוארכים לשנת 1999, והם מוגדרים באופן רחב למדי. אי אפשר לדעת בוודאות אם קובץ, כמו קובץ CSS או תמונה, יוחזר מהרשת או ייטען מהמטמון.
בפוסט הזה אדבר על ברירת מחדל מודרנית וחכמה לשמירת נתונים במטמון – ברירת מחדל שבה לא מתבצעת שמירת נתונים במטמון בכלל. אבל זו רק ברירת המחדל, ויש כמובן ניואנסים נוספים מעבר ל'השבתה'. המשך קריאה
יעדים
כשאתר נטען בפעם השנייה, יש לכם שני יעדים:
- מוודאים שהמשתמשים מקבלים את הגרסה העדכנית ביותר שזמינה – אם שיניתם משהו, הוא אמור להופיע במהירות
- לבצע את הפעולה הראשונה תוך אחזור כמה שפחות מהרשת
במובן הרחב ביותר, אתם רוצים לשלוח ללקוחות רק את השינוי הקטן ביותר כשהם יטענו את האתר שוב. בנוסף, קשה מאוד לבנות את האתר כך שכל שינוי יפורסם בצורה יעילה ככל האפשר (מידע נוסף על כך מופיע בהמשך ובסרטון).
עם זאת, יש גם פקדים אחרים שאפשר להשתמש בהם כשמדברים על אחסון במטמון – אולי החלטתם לאפשר למטמון ה-HTTP של הדפדפן של המשתמש לשמור את האתר שלכם במשך זמן רב, כדי שלא יידרשו בקשות רשת בכלל כדי להציג אותו. לחלופין, יכול להיות שיצרתם קובץ שירות (service worker) שיציג אתר באופן אופליין לחלוטין לפני שהוא יבדוק אם האתר מעודכן. זוהי אפשרות קיצונית, חוקית ומוצלחת בתחומים רבים של חוויית שימוש באינטרנט שמבוססת על אפליקציות אופליין, אבל האינטרנט לא צריך להיות קיצוני במיוחד, גם לא קיצוני במיוחד בנושא מטמון או בנושא רשתות בלבד.
רקע
כמפתחי אינטרנט, כולנו רגילים לרעיון של 'מטמון לא עדכני'. אבל אנחנו יודעים, כמעט באופן אינסטינקטיבי, אילו כלים זמינים כדי לפתור את הבעיה: לבצע "רענון מלא", לפתוח חלון פרטי או להשתמש בשילוב כלשהו של כלי הפיתוח של הדפדפן כדי למחוק את הנתונים של אתר מסוים.
למשתמשים רגילים באינטרנט אין את אותו מותרות. לכן, בנוסף ליעדים המרכזיים שלנו, שכוללים הבטחה שהמשתמשים ייהנו מהטעינה השנייה, חשוב מאוד גם לוודא שהם לא יהיו מאוכזבים או ייתקלו בבעיות. (כדאי לצפות בסרטון כדי לשמוע איך כמעט גרמנו לאתר web.dev/live להיתקע).
קצת רקע: אחת הסיבות הנפוצות ל'מטמון לא עדכני' היא למעשה הגדרת ברירת המחדל של המטמון משנת 1999. הוא מסתמך על הכותרת Last-Modified
:

כל קובץ שאתם טוענים נשמר למשך 10% נוספים ממחזור החיים הנוכחי שלו, כפי שהוא מופיע בדפדפן. לדוגמה, אם index.html
נוצר לפני חודש, הוא יישמר במטמון של הדפדפן למשך עוד שלושה ימים בערך.
בעבר, זו הייתה כוונה טובה, אבל בגלל האינטגרציה ההדוקה של האתרים של היום, התנהגות ברירת המחדל הזו עלולה לגרום למצב שבו למשתמש יש קבצים שמיועדים לגרסאות שונות של האתר (למשל, קובץ ה-JS מהגרסה שפורסמה ביום שלישי וקובץ ה-CSS מהגרסה שפורסמה ביום שישי), כי הקבצים האלה לא עודכנו באותו זמן.
השביל המואר היטב
ברירת המחדל המודרנית לשמירת תוכן במטמון היא לא לשמור תוכן במטמון בכלל, ולהשתמש ב-CDN כדי לקרב את התוכן למשתמשים. בכל פעם שמשתמש טוען את האתר, הוא עובר לרשת כדי לבדוק אם הוא מעודכן. זמן האחזור של הבקשה הזו יהיה קצר, כי היא תסופק על ידי רשת CDN שנמצאת בסמיכות גיאוגרפית לכל משתמש קצה.
אפשר להגדיר את מארח האינטרנט כך שיגיב לבקשות אינטרנט באמצעות הכותרת הזו:
Cache-Control: max-age=0,must-revalidate,public
פירוש הדבר הוא שהקובץ תקף לזמן קצר מאוד, וצריך לאמת אותו מהרשת כדי שאפשר יהיה להשתמש בו שוב (אחרת הוא רק 'מוצע').
תהליך האימות הזה זול יחסית מבחינת הבייטים המועברים – אם קובץ תמונה גדול לא השתנה, הדפדפן יקבל תגובה קטנה מסוג 304 – אבל הוא כרוך בזמן אחזור כי המשתמש עדיין צריך לעבור לרשת כדי לבדוק. וזה החיסרון העיקרי של הגישה הזו. הפתרון הזה יכול להתאים מאוד לאנשים עם חיבורים מהירים בעולם הראשון, ובמקומות שבהם ל-CDN שבחרתם יש כיסוי מצוין, אבל לא לאנשים עם חיבורים איטיים יותר בנייד או עם תשתית חלשה.
עם זאת, זוהי גישה מודרנית שהיא ברירת המחדל ב-CDN פופולרי, Netlify, אבל אפשר להגדיר אותה כמעט בכל CDN. ב-Firebase Hosting, אפשר לכלול את הכותרת הזו בקטע האירוח בקובץ firebase.json:
"headers": [
// Be sure to put this last, to not override other headers
{
"source": "**",
"headers": [ {
"key": "Cache-Control",
"value": "max-age=0,must-revalidate,public"
}
}
]
לכן, עדיין מומלץ להשתמש באפשרות הזו כברירת מחדל הגיונית, אבל חשוב לזכור שזו רק ברירת המחדל. בהמשך מוסבר איך להיכנס לתמונה ולשדרג את הגדרות ברירת המחדל.
כתובות URL עם טביעת אצבע
אם תכללו גיבוב של תוכן הקובץ בשם של נכסים, תמונות וכו' שמוצגים באתר, תוכלו להבטיח שלקבצים האלה תמיד יהיה תוכן ייחודי. לדוגמה, הקבצים יקראו sitecode.af12de.js
. כשהשרת שלכם מגיב לבקשות לקבצים האלה, אתם יכולים להורות לדפדפנים של משתמשי הקצה לשמור אותם במטמון למשך זמן רב, על ידי הגדרת הכותרת הבאה:
Cache-Control: max-age=31536000,immutable
הערך הזה הוא שנה, בשניות. לפי המפרט, זה שווה למעשה ל-"ללא הגבלת זמן".
חשוב לא ליצור את הגיבובים האלה באופן ידני – זו עבודה ידנית רבה מדי. תוכלו להשתמש בכלים כמו Webpack, Rollup וכו' כדי לעזור לכם בכך. מומלץ לקרוא מידע נוסף עליהם בדוח הכלים.
חשוב לזכור שאפשר להשתמש בחותמות אצבע לא רק ב-JavaScript, אלא גם בשמות של נכסים כמו סמלים, CSS וקובצי נתונים אחרים שלא ניתן לשנות. (כדאי גם לצפות בסרטון שלמעלה כדי לקבל מידע נוסף על חלוקת קוד, שמאפשרת לשלוח פחות קוד בכל פעם שמתבצע שינוי באתר).
לא משנה איך האתר שלכם משתמש במטמון, קבצים עם טביעות אצבע הם יקרים מאוד לכל אתר שתיצרו. רוב האתרים לא משתנים בכל גרסה.
כמובן, אי אפשר לשנות את השם של הדפים 'הידידותיים' שמוצגים למשתמשים באופן הזה: שינוי השם של הקובץ index.html
ל-index.abcd12.html
– זה לא אפשרי, אי אפשר לבקש מהמשתמשים לעבור לכתובת URL חדשה בכל פעם שהם טוענים את האתר! אי אפשר לשנות את השם של כתובות ה-URL ה'ידידותיות' האלה ולשמור אותן במטמון בדרך הזו, ולכן אני רוצה להציע פתרון ביניים אפשרי.
דרך ביניים
ברור שיש מקום לפשרה כשמדובר בשמירת נתונים במטמון. הצגתי שתי אפשרויות קיצוניות: אף פעם לא לשמור במטמון או לשמור במטמון תמיד. בנוסף, יש כמה קבצים שיכול להיות שתרצו לשמור במטמון לזמן מה, כמו כתובות ה-URL 'הידידותיות' שציינתי למעלה.
אם אתם רוצים לשמור במטמון את כתובות ה-URL 'הידידותיות' האלה ואת ה-HTML שלהן, כדאי לבדוק אילו יחסי תלות הן כוללות, איך הן עשויות להישמר במטמון ואיך השמירה במטמון של כתובות ה-URL שלהן לזמן מה עשויה להשפיע עליכם. נבחן דף HTML שכולל תמונה כזו:
<img src="/images/foo.jpeg" loading="lazy" />
אם תעדכנו או תשנו את האתר על ידי מחיקה או שינוי של התמונה הזו שנטענת באיטרציה, משתמשים שיציגו גרסה ששמורה במטמון של ה-HTML עשויים לראות תמונה שגויה או לא לראות תמונה בכלל – כי עדיין נשמרה במטמון הגרסה המקורית של /images/foo.jpeg
כשהם נכנסו שוב לאתר.
אם תהיו זהירים, יכול להיות שהשינוי הזה לא ישפיע עליכם. באופן כללי, חשוב לזכור שהאתר שלכם – אחרי שמשתמשי הקצה שומרים אותו במטמון – כבר לא קיים רק בשרתים שלכם. במקום זאת, הוא עשוי להתקיים בחלקים במטמון של הדפדפנים של משתמשי הקצה.
באופן כללי, רוב המדריכים בנושא מטמון מדברים על הגדרות כאלה – האם רוצים לשמור במטמון למשך שעה, כמה שעות וכו'. כדי להגדיר את סוג המטמון הזה, משתמשים בכותרת כזו (שמשמרת במטמון למשך 3600 שניות, שעה אחת):
Cache-Control: max-age=3600,immutable,public
עוד נקודה אחת. אם אתם יוצרים תוכן עדכני שלרוב המשתמשים ניגשים אליו רק פעם אחת – כמו כתבות חדשותיות – לדעתי לעולם לא כדאי לשמור אותו במטמון, אלא להשתמש בברירת המחדל הנבונה שציינתי למעלה. לדעתי, אנחנו לרוב מעריכים יתר על המידה את הערך של שמירת נתונים במטמון בהשוואה לרצון של המשתמשים לראות תמיד את התוכן העדכני והטוב ביותר, כמו עדכון קריטי לגבי כתבה חדשותית או אירוע נוכחי.
אפשרויות שאינן HTML
בנוסף ל-HTML, יש אפשרויות נוספות לקבצים שנמצאים באמצע הדרך:
באופן כללי, כדאי לחפש נכסים שלא משפיעים על אחרים
- לדוגמה: הימנעו משימוש ב-CSS, כי הוא גורם לשינויים באופן שבו ה-HTML מוצג
תמונות גדולות שמשמשות כחלק ממאמרים עדכניים
- סביר להניח שהמשתמשים לא ייכנסו למאמר מסוים יותר מכמה פעמים, לכן אין צורך לשמור תמונות או תמונות ראשיות (hero) במטמון לתמיד ולבזבז נפח אחסון.
נכס שמייצג משהו שיש לו משך חיים
- יכול להיות שנתוני JSON לגבי מזג האוויר יפורסמו רק כל שעה, כך שאפשר לשמור במטמון את התוצאה הקודמת למשך שעה – היא לא תשתנה בחלון הזמן
- יכול להיות שיהיו הגבלות קצב על גרסאות build של פרויקטים בקוד פתוח, לכן כדאי לשמור בזיכרון מטמון תמונה של סטטוס ה-build עד שיכול להיות שהסטטוס ישתנה
סיכום
כשמשתמשים טוענים את האתר שלכם בפעם השנייה, כבר יש לכם אישור מהם שהם רוצים לחזור ולקבל עוד ממה שאתם מציעים. בשלב הזה, לא תמיד מדובר רק בקיצור זמן הטעינה. יש לכם כמה אפשרויות שיעזרו לכם לוודא שהדפדפן מבצע רק את העבודה שהוא צריך כדי לספק חוויה מהירה ועדכנית.
אחסון במטמון הוא לא קונספט חדש באינטרנט, אבל אולי כדאי להגדיר לו ברירת מחדל הגיונית. מומלץ להשתמש בהגדרה כזו ולהביע הסכמה לאסטרטגיות אחסון טובות יותר במטמון כשיש צורך בהן. תודה על שקראת מידע זה!
ראה גם
למדריך כללי בנושא מטמון HTTP, אפשר לעיין במאמר מניעת בקשות מיותרות ברשת באמצעות מטמון HTTP.