אחזור משאבים ברשת הוא איטי ויקר:
- תגובות גדולות דורשות הרבה מעברים הלוך ושוב בין הדפדפן לשרת.
- הדף לא ייטען עד שכל המשאבים הקריטיים שלו יורדו באופן מלא.
- אם מישהו נכנס לאתר שלכם עם חבילת גלישה מוגבלת, כל בקשה מיותרת לרשת היא בזבוז כסף.
איך אפשר להימנע מבקשות מיותרות לרשת? מטמון ה-HTTP של הדפדפן הוא קו ההגנה הראשון שלכם. זו לא בהכרח הגישה הגמישה או החזקה ביותר, ויש לכם שליטה מוגבלת על משך החיים של תגובות שנשמרו במטמון, אבל היא יעילה, יש בה תמיכה בכל הדפדפנים, ולא צריך הרבה עבודה.
במדריך הזה תלמדו את העקרונות הבסיסיים של הטמעה יעילה של שמירה במטמון HTTP.
תאימות דפדפן
אין למעשה ממשק API אחד שנקרא 'מטמון HTTP'. זה השם הכללי של אוסף ממשקי API בפלטפורמת האינטרנט. ממשקי ה-API האלה נתמכים בכל הדפדפנים:
Cache-Control
ETag
Last-Modified
איך פועל מטמון HTTP
כל בקשות ה-HTTP שהדפדפן שולח מנותבות תחילה למטמון של הדפדפן, כדי לבדוק אם יש תגובה חוקית שנשמרה במטמון שאפשר להשתמש בה לביצוע הבקשה. אם קיימת התאמה, התגובה קוראת מהמטמון, וכך מבטלים גם את זמן האחזור של הרשת וגם את עלויות הנתונים שההעברה נגרמת.
ההתנהגות של מטמון HTTP נשלטת על ידי שילוב של כותרות בקשות וכותרות תשובות. בתרחיש אידיאלי, תהיה לכם שליטה גם על הקוד של אפליקציית האינטרנט (שיקבע את כותרות הבקשות) וגם על התצורה של שרת האינטרנט (שיקבעו את כותרות התגובה).
לסקירה מפורטת יותר של מושגים אפשר לעיין במאמר שמירה במטמון HTTP של ה-MDN.
כותרות של בקשות: להישאר עם ברירות המחדל (בדרך כלל)
יש כמה כותרות חשובות שצריך לכלול בבקשות היוצאות של אפליקציית האינטרנט שלכם, אבל הדפדפן כמעט תמיד מגדיר אותן בשבילכם כשהוא שולח בקשות. כותרות של בקשות שמשפיעות על בדיקת העדכניות, כמו If-None-Match
ו-If-Modified-Since
, מופיעות בהתאם להבנה של הדפדפן לגבי הערכים הנוכחיים במטמון ה-HTTP.
אלה חדשות טובות — המשמעות היא שאפשר להמשיך לכלול תגים כמו <img src="my-image.png">
ב-HTML, והדפדפן יטפל עבורכם אוטומטית בשמירת HTTP במטמון, ללא מאמץ נוסף.
כותרות תגובה: הגדרת שרת האינטרנט
החלק החשוב ביותר בהגדרת שמירת ה-HTTP במטמון הוא הכותרות ששרת האינטרנט מוסיף לכל תגובה יוצאת. הכותרות הבאות מביאות בחשבון את ההתנהגות היעילה של השמירה במטמון:
Cache-Control
. השרת יכול להחזיר הוראתCache-Control
כדי לציין איך ולמשך כמה זמן, הדפדפן ומטמוני ביניים אחרים צריכים לשמור את התגובה הבודדת במטמון.ETag
. כשהדפדפן מאתר תגובה שנשמרה במטמון שפג תוקפה, הוא יכול לשלוח לשרת אסימון קטן (בדרך כלל גיבוב (hash) של תוכן הקובץ) כדי לבדוק אם הקובץ השתנה. אם השרת מחזיר את אותו אסימון, הקובץ זהה ואין צורך להוריד אותו מחדש.Last-Modified
. הכותרת הזו משמשת לאותה מטרה כמוETag
, אבל היא משתמשת באסטרטגיה מבוססת-זמן כדי לקבוע אם משאב השתנה, בניגוד לאסטרטגיה מבוססת-התוכן שלETag
.
בשרתי אינטרנט מסוימים יש תמיכה מובנית בהגדרת הכותרות האלו כברירת מחדל, בעוד שאחרים לא כוללים את הכותרות האלו לחלוטין, אלא אם מגדירים אותן באופן מפורש. הפרטים הספציפיים לגבי האופן להגדרת כותרות משתנים באופן משמעותי בהתאם לשרת האינטרנט שבו אתם משתמשים. מומלץ לעיין בתיעוד של השרת כדי לקבל את הפרטים המדויקים ביותר.
כדי לחסוך לכם חיפושים, הנה הוראות להגדרה של כמה שרתי אינטרנט פופולריים:
אם משמיטים את כותרת התשובה Cache-Control
, השמירה במטמון של HTTP לא מושבתת. במקום זאת, דפדפנים מנחשים בפועל את סוג התנהגות השמירה במטמון המתאימה ביותר לסוג תוכן מסוים. סביר להניח שאתם רוצים יותר שליטה מההצעות, לכן כדאי להקדיש זמן להגדרת כותרות התגובות.
באילו ערכים של כותרות תגובה כדאי להשתמש?
יש שני תרחישים חשובים שצריך ללמוד כשמגדירים את כותרות התגובה של שרת האינטרנט.
שמירה במטמון לטווח ארוך של כתובות URL שיש להן גרסאות
נניח שהשרת מורה לדפדפנים לשמור קובץ CSS במטמון למשך שנה (Cache-Control: max-age=31536000
), אבל המעצב ביצע עדכון למקרה חירום שצריך לפרוס באופן מיידי. איך מודיעים לדפדפנים לעדכן את עותק המטמון 'לא פעיל' של הקובץ? אי אפשר, לפחות לא בלי לשנות את כתובת ה-URL של המשאב.
אחרי שהדפדפן שומר את התגובה במטמון, נעשה שימוש בגרסת המטמון עד שהיא מפסיקה לפעול, כפי שנקבע על ידי max-age
או expires
, או עד שהיא מוסרת מהמטמון מסיבה אחרת כלשהי. למשל, על ידי ניקוי המטמון של הדפדפן. כתוצאה מכך, משתמשים שונים עשויים להשתמש בגרסאות שונות של הקובץ בזמן בניית הדף: משתמשים שאחזרו את המשאב משתמשים בגרסה החדשה, ומשתמשים ששמרו במטמון עותק קודם (אבל עדיין חוקי) משתמשים בגרסה ישנה יותר של התגובה שלו.
איך אפשר לנצל את שני העולמות: שמירה במטמון בצד הלקוח ועדכונים מהירים? אתם משנים את כתובת ה-URL של המשאב ומאלצים את המשתמש להוריד את התגובה החדשה בכל פעם שהתוכן שלה משתנה. בדרך כלל אפשר לעשות זאת על ידי הטמעת טביעת אצבע של הקובץ או מספר גרסה שלו, בשם הקובץ שלו – לדוגמה style.x234dff.css
.
כשמגיבים לבקשות לכתובות URL שמכילות "טביעת אצבע" או מידע על ניהול גרסאות, והתוכן שלהן לא אמור להשתנות אף פעם, צריך להוסיף את Cache-Control: max-age=31536000
לתשובות.
הגדרת הערך הזה מנחה את הדפדפן שכשהוא יצטרך לטעון את אותה כתובת URL במהלך השנה הבאה (31,536,000 שניות, הערך המקסימלי הנתמך), הוא יוכל להשתמש באופן מיידי בערך ששמור במטמון ה-HTTP, בלי שתצטרכו להגיש בקשת רשת לשרת האינטרנט שלכם. זה נהדר - כך הבנתם מיד את האמינות והמהירות כתוצאה מההימנעות מהרשת!
כלים כמו Webpack יכולים לבצע אוטומציה של תהליך ההקצאה של טביעות אצבע מגובבות (hash) לכתובות ה-URL של הנכסים.
אימות מחדש של שרת לכתובות URL ללא גרסאות
לצערנו, לא לכל כתובות ה-URL שטוענים יש גרסאות. יכול להיות שלא תוכלו לכלול שלב build לפני פריסת אפליקציית האינטרנט, ולכן לא תוכלו להוסיף גיבובים לכתובות ה-URL של הנכסים. וכל אפליקציית אינטרנט צריכה קובצי HTML — הקבצים האלה (כמעט!) אף פעם לא יכללו מידע על ניהול גרסאות, כי אף אחד לא יטרח להשתמש באפליקציית האינטרנט שלכם אם צריך לזכור שכתובת ה-URL כדי לבקר בה היא https://example.com/index.34def12.html
. אז מה אפשר לעשות לגבי כתובות ה-URL האלה?
זהו תרחיש אחד שבו תצטרכו להכיר בהפסד שלכם. השמירה במטמון HTTP לבדו לא חזקה מספיק כדי להימנע לגמרי מהרשת. (אל דאגה, בקרוב תלמדו על קובץ השירות (service worker), שיספק את התמיכה הדרושה כדי להילחם לטובתכם.) עם זאת, יש כמה פעולות שאפשר לבצע כדי להבטיח שבקשות הרשת יהיו מהירות ויעילות ככל האפשר.
הערכים הבאים של Cache-Control
יכולים לעזור לך לכוונן בצורה עדינה את המיקום והאופן שבו כתובות URL שאין להן גרסאות נשמרות במטמון:
no-cache
. זהו הוראה לדפדפן שעליו לאמת מחדש מול השרת בכל פעם שהוא משתמש בגרסה שנשמרה במטמון של כתובת ה-URL.no-store
. זה מורה לדפדפן ולמטמון ביניים אחרים (כמו CDN) לעולם לא לאחסן אף גרסה של הקובץ.private
. דפדפנים יכולים לשמור את הקובץ במטמון, אבל מטמון ביניים לא יכול לעשות זאת.public
. אפשר לשמור את התגובה בכל מטמון.
אפשר לעיין בנספח: תרשים זרימה של Cache-Control
כדי להמחיש את תהליך ההחלטה באילו ערכים של Cache-Control
להשתמש. Cache-Control
יכול לקבל גם רשימת הוראות שמופרדות בפסיקים. פרטים נוספים זמינים בנספח: Cache-Control
דוגמאות.
גם הגדרה של ETag
או Last-Modified
יכולה לעזור. כפי שצוין בכותרות התגובות, ETag
ו-Last-Modified
משרתים את אותה מטרה: לקבוע אם הדפדפן צריך להוריד מחדש קובץ שנשמר במטמון שפג תוקפו. מומלץ להשתמש בETag
כי היא מדויקת יותר.
נניח שחלפו 120 שניות מאז השליפה הראשונית, והדפדפן שלח בקשה חדשה לגבי אותו משאב. ראשית, הדפדפן בודק את מטמון ה-HTTP ומוצא את התגובה הקודמת. לצערנו, הדפדפן לא יכול להשתמש בתשובה הקודמת כי פג התוקף של התשובה. בשלב הזה, הדפדפן יוכל לשלוח בקשה חדשה ולאחזר את התגובה המלאה החדשה. עם זאת, הפעולה הזו לא יעילה כי אם המשאב לא השתנה, אין סיבה להוריד את אותו המידע שכבר נמצא במטמון!
זו הבעיה שאסימוני אימות, כפי שמצוין בכותרת ETag
, נועדו לפתור. השרת יוצר ומחזיר אסימון שרירותי, שהוא בדרך כלל גיבוב (hash) או טביעת אצבע אחרת של תוכן הקובץ. הדפדפן לא צריך לדעת איך נוצרת טביעת האצבע – הוא צריך רק לשלוח אותה לשרת בבקשה הבאה. אם טביעת האצבע לא השתנתה, המשאב לא השתנה והדפדפן יכול לדלג על ההורדה.
אם מגדירים את ETag
או Last-Modified
, בקשת האימות מחדש יכולה להיות יעילה הרבה יותר כי היא מאפשרת לה להפעיל את כותרות הבקשות If-Modified-Since
או If-None-Match
שהוזכרו בכותרות של בקשות.
כששרת אינטרנט שהוגדר כראוי רואה את הכותרות של הבקשות הנכנסות, הוא יכול לאשר אם הגרסה של המשאב שכבר נמצא במטמון ה-HTTP של הדפדפן תואמת לגרסה האחרונה בשרת האינטרנט. אם יש התאמה, השרת יכול להגיב באמצעות תגובת HTTP 304 Not Modified
, המקבילה למילים "היי, ממשיכים להשתמש במה שכבר קיבלת!" יש מעט מאוד נתונים להעביר בעת שליחת תגובה מהסוג הזה, לכן בדרך כלל התהליך מהיר בהרבה מהצורך לשלוח בחזרה עותק של המשאב עצמו.
![תצוגה חזותית של לקוח שמבקש משאב והשרת מגיב עם כותרת 304.](https://web.dev/static/articles/http-cache/image/a-diagram-a-client-reque-3e18455532e4e.png?authuser=5&hl=he)
/file
מהשרת, וכולל את הכותרת If-None-Match
, כדי להנחות את השרת להחזיר את הקובץ המלא רק אם ETag
של הקובץ בשרת לא תואם לערך If-None-Match
של הדפדפן. במקרה הזה, 2 הערכים תואמים, ולכן השרת מחזיר תגובת 304 Not Modified
עם הוראות לגבי משך הזמן לשמירת הקובץ במטמון (Cache-Control: max-age=120
).
סיכום
מטמון ה-HTTP הוא דרך יעילה לשפר את ביצועי העומסים, מפני שהוא מצמצם בקשות רשת מיותרות. הוא נתמך בכל הדפדפנים, והגדרתו לא דורשת יותר מדי מאמץ.
ההגדרות הבאות של Cache-Control
יכולות להיות התחלה טובה:
Cache-Control: no-cache
למשאבים שצריך לאמת מחדש מול השרת לפני כל שימוש.Cache-Control: no-store
למשאבים שאף פעם לא צריכים להישמר במטמון.Cache-Control: max-age=31536000
למשאבים עם גרסאות.
בנוסף, הכותרת ETag
או Last-Modified
יכולה לעזור לך לאמת מחדש ביעילות רבה יותר משאבי מטמון שתוקפם פג.
מידע נוסף
אם אתם מחפשים מידע מעמיק יותר מהעקרונות הבסיסיים של השימוש בכותרת Cache-Control
, כדאי לעיין במדריך של ג'ייק ארצ'יבלד, שיטות מומלצות לשמירה במטמון והגדרות גיל מקסימלי.
במאמר שימוש במטמון המטמון מוסבר איך לבצע אופטימיזציה של השימוש במטמון למבקרים חוזרים.
נספח: טיפים נוספים
אם יש לכם יותר זמן, הנה עוד דרכים שבהן תוכלו לבצע אופטימיזציה של השימוש במטמון ה-HTTP:
- להשתמש בכתובות URL עקביות. אם מציגים תוכן זהה בכתובות URL שונות, התוכן יאוחזר ויאוחסן מספר פעמים.
- צמצום הנטישה. אם חלק ממשאב (כמו קובץ CSS) מתעדכן לעיתים קרובות, ואילו שאר הקובץ לא מתעדכן (כמו קוד ספרייה), כדאי לפצל את הקוד שעודכן לעיתים קרובות לקובץ נפרד ולהשתמש באסטרטגיית שמירה במטמון למשך זמן קצר בשביל הקוד שמתעדכן לעיתים קרובות, ואסטרטגיה למשך זמן ארוך של שמירה במטמון לקוד שלא משתנה לעיתים קרובות.
- אם אפשר להגדיר מידה מסוימת של חוסר פעילות במדיניות
Cache-Control
, כדאי לעיין בהנחיה החדשהstale-while-revalidate
.
נספח: תרשים זרימה של Cache-Control
![תרשים זרימה](https://web.dev/static/articles/http-cache/image/flowchart-8943547beafd6.png?authuser=5&hl=he)
Cache-Control
.
נספח: Cache-Control
דוגמאות
ערך של Cache-Control |
הסבר |
---|---|
max-age=86400 |
אפשר לשמור את התגובה במטמון על ידי דפדפנים ומטמון ביניים למשך עד יום אחד (60 שניות x 60 דקות x 24 שעות). |
private, max-age=600 |
הדפדפן יכול לשמור את התגובה במטמון (אבל לא במטמון ביניים) למשך עד 10 דקות (60 שניות x 10 דקות). |
public, max-age=31536000 |
אפשר לשמור את התגובה בכל מטמון למשך שנה. |
no-store |
אי אפשר לשמור את התגובה במטמון ויש לאחזר אותה במלואה בכל בקשה. |