כמעט בטוח שהרצתם בדיקת מהירות, ראיתם אזהרה על "leverage browser caching", וסגרתם את הטאב מתוך בלבול. זה בסדר. כותרות cache נשמעות כמו משהו שרק מפתחי backend צריכים לגעת בו. אבל כשמבינים את הרעיון הבסיסי, זה די פשוט, ולתקן את זה יכול לחסוך זמן אמיתי בכל ביקור חוזר באתר שלכם.
הבה נפרק מה הכותרות האלה בעצם עושות, אילו מהן חשובות, ואיך להגדיר אותן בלי לשבור שום דבר.
מה כותרות Cache בדפדפן בעצם עושות
בכל פעם שמישהו נכנס לאתר שלכם, הדפדפן שלו מוריד קבוצה של קבצים: הלוגו, גיליון העיצוב, חלקי JavaScript, אולי גם פונט או שניים. בלי הנחיות cache, הדפדפן יצטרך להוריד את כל זה מחדש בביקור הבא, גם אם שום דבר לא השתנה.
כותרות cache הן הוראות שהשרת שלכם שולח בצירוף לכל קובץ, שאומרות לדפדפן: "היי, אתה יכול לשמור את זה קצת. אין צורך לבקש ממני את זה שוב." זה כל הרעיון. המורכבות מגיעה מבחירת ההוראות הנכונות לכל סוג קובץ.
שתי הכותרות החשובות ביותר
יש כמה כותרות HTTP שקשורות לזה, אבל שתיים עושות את רוב העבודה:
- Cache-Control - אומרת לדפדפן כמה זמן לשמור קובץ ובאילו תנאים
- ETag - "חותמת" של תוכן הקובץ, שמשמשת לבדוק אם הוא השתנה בלי להוריד אותו מחדש
תראו גם את Expires בהגדרות ישנות יותר, אבל Cache-Control החליפה אותה ברובם המקרים כי היא גמישה יותר.
הגדרת cache בשרת שאפשר ליישם בפועל
הנה נקודת התחלה מעשית להגדרת cache בשרת שרוב האתרים יכולים להשתמש בה בלי בעיות. הדוגמה הזו נכתבה עבור Nginx, אבל ההיגיון תקף בכל מקום.
location ~* \.(jpg|jpeg|png|webp|gif|svg|woff2|woff)$ { expires 30d; add_header Cache-Control "public, immutable"; } location ~* \.(css|js)$ { expires 7d; add_header Cache-Control "public"; } location ~* \.(html)$ { add_header Cache-Control "no-cache"; }שימו לב לתבנית: תמונות ופונטים מקבלים זמני cache ארוכים כי הם משתנים לעיתים רחוקות. קבצי CSS ו-JS מקבלים חלון קצר יותר כי הם מתעדכנים לרוב בתדירות גבוהה יותר בזמן פיתוח פעיל. HTML מקבל כמעט אפס cache, כי אתם רוצים שהמבקרים יקבלו תמיד את הגרסה העדכנית ביותר של מבנה העמוד עצמו.
למה "immutable" חשובה
ההנחיה immutable אומרת לדפדפן לא לבדוק אפילו אם הקובץ השתנה, עד שזמן ה-cache מסתיים. זה חוסך תקשורת רשת קטנה אבל אמיתית שנקראת "בקשת אימות מחדש" (revalidation request). לגבי נכסים עם hash בגרסה בשם הקובץ (כמו app.a3f8c1.js), זה בטוח לחלוטין, כי שינוי בתוכן תמיד יוצר שם קובץ חדש.
הטריק של Hash בשם הקובץ
זה החלק שאנשים מפספסים. זמני cache ארוכים עובדים טוב רק אם תהליך הבנייה שלכם משנה את שם הקובץ בכל פעם שהתוכן משתנה. רוב כלי הבנייה המודרניים (Webpack, Vite, esbuild) עושים את זה אוטומטית, ומוסיפים hash כמו -8f92ab לשם הקובץ.
בלי זה, הייתם צריכים לבחור בין שתי אפשרויות לא טובות: לשמור cache באגרסיביות ולהסתכן שהמבקרים יראו CSS ישן ושבור, או לשמור cache מינימלי ולהפסיד את יתרון הביצועים בכלל. עם שמות קבצים עם hash, אתם מקבלים את הטוב משני העולמות. שומרים cache לתמיד, וברגע שהתוכן משתנה, גם ה-URL משתנה, כך שהדפדפן חייב להוריד גרסה חדשה.
מדידת ההשפעה בעולם האמיתי
הגדרת cache בשרת שנעשית טוב מופיעה בבירור בכמה מדדים:
- זמן טעינה בביקור חוזר - צריך לרדת בצורה משמעותית, לרוב 40-70% מהיר יותר מביקור ראשון
- סך הבייטים שמועברים - אפשר לבדוק את זה בטאב Network של Chrome DevTools בטעינה שנייה של העמוד. קבצים ששמורים ב-cache מציגים "(disk cache)" או "(memory cache)" במקום גודל העברה
- Time to Interactive - משתפר כי הדפדפן חוסך הורדות כפולות ומעבד קבצי JS ששמורים ב-cache מהר יותר
אתם יכולים לאמת שהכותרות שלכם באמת פועלות על ידי פתיחת DevTools, כניסה לטאב Network, וטעינה חדשה של העמוד. לחצו על כל נכס סטטי ובדקו את הכותרות בתגובה (Response Headers) שיש Cache-Control. אם היא חסרה לגמרי, השרת שלכם לא שולח הוראות cache כלל, וכל ביקור מתנהג כמו ביקור ראשון.
טעויות נפוצות שמבטלות את הגדרת ה-cache בשרת
שמירת HTML ב-cache בצורה אגרסיבית מדי
אם אתם שומרים עמודי HTML בפועל ב-cache למשך ימים, המבקרים אולי לא יראו עדכוני תוכן, שינויי מחירים, או פוסטים חדשים בבלוג לזמן ארוך. שמרו על HTML במדיניות קצרה או בלי cache כלל, ותנו לנכסים הסטטיים שלכם לשאת את משכי ה-cache הארוכים.
לשכוח מ-Query Strings
הגדרות ישנות מסוימות משתמשות ב-style.css?v=2 כדי לכפות רענון cache. זה עובד, אבל זה פחות אמין ב-CDN-ים ובפרוקסי לעומת hash אמיתי בשם הקובץ. אם אתם יכולים לעבור לשמות קבצים עם hash, כדאי לעשות את זה.
בלי כותרות Cache בתגובות API
נכסים סטטיים אינם היחידים שנהנים מזה. אם יש לכם endpoints של API שמחזירים מידע שמשתנה לעיתים רחוקות, כמו רשימת מדינות או קטגוריות, כותרת קצרה כמו Cache-Control: public, max-age=300 יכולה להפחית עומס על השרת בצורה משמעותית בלי סיכון אמיתי לבעיות של מידע לא עדכני.
איפה Cache בצד השרת משתלב
Cache בדפדפן מטפל בביקורים חוזרים מאותו אדם. אבל רוב התעבורה שלכם היא מבקרים חדשים, ושם cache בצד השרת (page cache, object cache, cache ב-CDN) עושה את העבודה הכבדה. כיסינו את הצד הזה בפירוט במאמרים איך להגדיר Redis Caching בשרת בלי לשבור שום דבר וגם Memcached לעומת Redis: איזו שכבת cache מתאימה לשרת שלכם, אם תרצו להעמיק בצד הזה של המערכת.
אם אתם מריצים WordPress, הרבה מהדברים האלה מתטפלים באופן אוטומטי כשמפעילים את ההגדרות הנכונות. cache בשכבת העמוד, שיפור ביצועים של נכסים, ואפילו object caching מבוסס Redis לשאילתות מסד הנתונים, יכולים לרוץ בלי שתצטרכו לגעת בקובץ תצורה בעצמכם, וזה שווה לדעת אם אתם מעדיפים להשקיע את הזמן שלכם בתוכן ולא בהגדרות שרת. אפשר לקרוא עוד על cache בשרת ועל Redis caching אם זה הכיוון שאתם רוצים לקחת.
סיכום פשוט
כותרות cache בדפדפן אינן מסובכות כשרואים את התבנית: שמרו נכסים סטטיים עם hash ב-cache באגרסיביות, שמרו על HTML עדכני, ואמתו שזה בפועל עובד ב-DevTools במקום להניח שזה כך. תעשו את זה, והמבקרים החוזרים שלכם ישימו לב להבדל באופן מיידי, גם אם לא יידעו להסביר למה.