אהבת את המטמון ❤️

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

הפוסט הזה הוא נלווה לסרטון Love yourcache, חלק מהתוכן המורחב ב-Chrome Dev Summit 2020. חשוב לצפות בסרטון:

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

בפוסט הזה אדבר על ברירת מחדל סבירה ומודרנית לשמירה במטמון, כזו שלא מאפשרת שמירה במטמון בכלל. אבל זו רק ברירת המחדל, והיא כמובן מעודכנת יותר מ"לכבות את זה". המשיכו לקרוא!

שערים

כשאתר נטען בפעם השנייה, יש שתי מטרות:

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

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

יחד עם זאת, כשאתם שוקלים לשמור במטמון יש גם כפתורים אחרים – אולי החלטתם לאפשר למטמון ה-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, אפשר לכלול את הכותרת הזו בקטע האירוח בקובץ 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 יכול להפיק תועלת מכתובות URL בטביעת אצבע; אפשר לתת את השם הזה גם לנכסים כמו סמלים, CSS וקובצי נתונים אחרים שאינם משתנים. (ובנוסף, אל תשכחו לצפות בסרטון שלמעלה כדי לקבל מידע נוסף על פיצול קוד, שמאפשר לכם לשלוח פחות קוד בכל פעם שהאתר שלכם משתנה).

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

כמובן, אנחנו לא יכולים לשנות את השמות של הדפים 'ידידותיים' למשתמשים' באופן הזה: שינוי השם של קובץ index.html לשם index.abcd12.html - אי אפשר לבקש מהמשתמשים לעבור לכתובת URL חדשה בכל פעם שהם טוענים את האתר! כך אי אפשר לשנות את השם של כתובות ה-URL ה'ידידותיות' האלה ולשמור אותן במטמון, וזה מוביל אותי לשלב ביניים אפשרי.

הקרקע האמצעית

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

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

<img src="/images/foo.jpeg" loading="lazy" />

אם מעדכנים או משנים את האתר על ידי מחיקה או שינוי של התמונה שנטענת באופן מדורג, משתמשים שצופים בגרסה שנשמרה במטמון של ה-HTML עשויים לקבל תמונה שגויה או חסרה – כי הם עדיין שמרו את הקובץ /images/foo.jpeg המקורי במטמון כשהם יבקרו באתר.

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

באופן כללי, רוב המדריכים לגבי שמירה במטמון ידברו על הגדרה כזו – האם אתם רוצים לשמור במטמון למשך שעה, מספר שעות וכן הלאה. כדי להגדיר את סוג המטמון הזה, השתמשו בכותרת כמו זו (שנשמורה במטמון למשך 3, 600 שניות או שעה אחת):

Cache-Control: max-age=3600,immutable,public

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

אפשרויות שאינן HTML

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

  • באופן כללי, כדאי לחפש נכסים שלא משפיעים על אחרים

    • לדוגמה: יש להימנע מ-CSS, מכיוון שהוא גורם לשינויים באופן עיבוד ה-HTML
  • תמונות גדולות שמשמשות כחלק ממאמרים עדכניים

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

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

סיכום

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

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

כדאי לעיין גם בפרטים הבאים

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