מטמון הדפדפן מאפשר להשתמש שוב בתגובת HTTP במקום להוריד את אותו משאב מחדש. לקבצים ציבוריים שכתובתם משתנה עם התוכן נותנים תוקף ארוך, ל-HTML שחייב להישאר מעודכן דורשים אימות, ועל תגובות אישיות מגינים במפורש. מדיניות יעילה היא הסכם על שימוש חוזר ועדכונים, לא ערך max-age ארוך לכל כתובת.
מבדילים בין תגובה טרייה, ישנה ומאומתת
המטמון שומר גוף תגובה וכותרות רלוונטיות. כל עוד התגובה טרייה, אפשר להשתמש בה בלי לשאול את השרת. לאחר מכן בדרך כלל נדרש קשר ברשת, אלא אם המדיניות מתירה תוכן ישן. פקיעת תוקף אינה מוחקת מיד את הקובץ אלא משנה את תנאי השימוש.
אימות בודק אם העותק מתאים לייצוג הנוכחי. אם כן, השרת יכול להחזיר 304 Not Modified ללא הגוף. נחסכים בתים, אך עדיין יש בקשה ותגובה. שימוש בעותק מקומי טרי חוסך את הסבב עצמו, ולכן אלה תוצאות ביצועים שונות.
מטמון פרטי של דפדפן שונה ממטמון משותף של proxy או CDN. תגובה שמתאימה לאדם אחד עלולה להיות אסורה לאחר. מתייחסים לכך כחלק מתכנון היישום. המדריך לזמן תגובת השרת מסביר היכן מתבצעת עבודת המקור; מטמון משנה את תדירותה, לא בהכרח את מהירות הפעולה הלא שמורה.
מתאימים את Cache-Control לתגובה
ההוראות קובעות הרשאות שונות. בפרט, no-cache אינו איסור אחסון למרות שמו.
| הוראה | משמעות בתגובה | החלטה מתאימה |
|---|---|---|
max-age=N |
משך טריות בשניות | כמה זמן להשתמש בלי אימות |
s-maxage=N |
משך טריות במטמון משותף | הפרדת CDN ודפדפן |
no-cache |
אימות לפני שימוש חוזר | HTML שמור אך מעודכן |
no-store |
אין לשמור תגובה | תוכן רגיש שאסור לאחסן |
private |
אין לשמור במטמון משותף | הגבלת תוכן אישי למטמון פרטי |
public |
מתיר אחסון משותף בכפוף לכללים האחרים | שיתוף מכוון של תוכן ציבורי |
immutable |
הייצוג לא ישתנה בזמן הטריות | קבצים עם טביעת תוכן |
must-revalidate |
אין שימוש בתגובה ישנה בלי אימות מוצלח | מניעת תוכן ישן שלא אומת |
Cookie לבדו אינו הופך תגובה לפרטית באופן אמין. מגדירים מדיניות ומוודאים שה-CDN אינו עוקף אותה. private אינו מצפין ואינו מונע שמירה בדפדפן. לתגובת חשבון רגישה שאסור לשמור משתמשים ב-Cache-Control: no-store ומגדירים גם עקיפת מטמון משותף.
לא מצרפים הוראות סותרות באופן אוטומטי. כלל ברור קל יותר לבדיקה. הוספת no-store עכשיו אינה מחזירה עותקים שכבר נשמרו לפי מדיניות ישנה ומתירנית. מתכננים תיקון וביטול תוקף בנפרד. מדריך מטמון HTTP של MDN מסביר את המודל.
משנים כתובת כאשר הקובץ משתנה
טביעת תוכן בשם הקובץ קושרת את הכתובת לתוצר בנייה מסוים. אם app.8f3a1c2d.js משתנה, מפרסמים שם חדש ומעדכנים את הפניית ה-HTML. הכתובת הישנה חייבת להמשיך להחזיר את התוכן הישן. החלפת הבתים בכתובת immutable מפרה את ההבטחה שמאפשרת תוקף ארוך.
זו דוגמה מקובלת למדיניות של קובץ ציבורי בעל טביעת תוכן.
Cache-Control: public, max-age=31536000, immutableהמספר הוא שנה בשניות, בחירת מדיניות ולא סף ביצועים מחייב. הדפדפן יכול לפנות את הקובץ מוקדם יותר בגלל מגבלת אחסון. תוקף ארוך מתיר שימוש חוזר, אך אינו מבטיח זמינות ללא רשת או שמירה בזיכרון.
מעלים קבצים לפני ה-HTML שמפנה אליהם ושומרים גרסאות קודמות עבור מסמכים ישנים וכרטיסיות פתוחות. import דינמי מאוחר יכול לבקש חבילה ישנה אחרי פריסה חדשה. מחיקה מידית עלולה להפוך עדכון רגיל לשגיאת פעולה. משתמשים במניפסט הבנייה ובמדיניות שימור מתאימה.
גם גרסה בפרמטר שאילתה יכולה לעבוד, אם כל המטמונים הרלוונטיים כוללים אותו במפתח. שם עם טביעת תוכן קל יותר לבדיקה. לא מוסיפים חותמת זמן חדשה לכל בקשה, משום שהיא מונעת שימוש חוזר בתוכן זהה.
מאמתים HTML עם ETag ו-Last-Modified
HTML ציבורי בכתובת קבועה מתאים לעיתים ל-Cache-Control: no-cache עם מאמתים מהשרת. ETag מזהה גרסת ייצוג ואינו חייב להיות hash. Last-Modified מספק זמן שינוי. הערכים חייבים להשתנות כשהייצוג משתנה, לרבות גרסאות תוכן רלוונטיות.
הדפדפן יכול לשלוח If-None-Match עם ה-ETag השמור. התאמה מחזירה 304, ואי התאמה את הייצוג הנוכחי. If-Modified-Since משתמש ב-Last-Modified לאימות לפי זמן. כאשר שניהם רלוונטיים, תנאי ה-ETag קודם. אין לקבע ETag אחד לכל העמודים והגרסאות.
לתוכן אישי שמותר לשמור בדפדפן אך לא ב-CDN אפשר להתחיל מ-private, no-cache. לתוכן רגיש יותר בוחרים no-store. בודקים התחברות, הרשאות ויציאה ביישום; כותרות אינן תחליף לבקרת גישה. כלל לקובץ סטטי אינו רשאי להפוך הורדה מאומתת לציבורית.
אימות חוסך העברה, אך לא תמיד את כל עבודת המקור. אם היישום מייצר את התגובה המלאה כדי לחשב ETag, נשאר עיבוד רב. מודדים העברה ועבודה בשרת לפני שמייחסים למטמון ירידה בעומס.
מגדירים Apache בתיקייה ציבורית ייעודית
קובץ .htaccess הבא מיועד רק לתיקייה של קבצים ציבוריים עם טביעת תוכן. הוא דורש Apache HTTP Server 2.4, מודול mod_headers והרשאת override מתאימה. זה אינו כלל לכל האתר, להעלאות או לייצוא חשבון רק בגלל סיומת מוכרת.
הכלל מזהה טביעה הקסדצימלית באותיות קטנות, באורך שמונה תווים לפחות, לפני סיומת מותרת.
# public/assets/.htaccess
<FilesMatch "\.[a-f0-9]{8,}\.(css|js|mjs|png|jpg|jpeg|webp|avif|svg|woff2)$">
Header set Cache-Control "public, max-age=31536000, immutable"
</FilesMatch>מדיניות HTML שייכת ליישום או למיקום שמייצר אותו בפועל. כלל שם קובץ אינו מכסה בהכרח נתיבים משוכתבים. אם מודול, framework או proxy כבר מגדיר Cache-Control, מסירים את החפיפה במקורה ובודקים כותרות כפולות בתוצאה. טבלאות כותרות והפניות פנימיות של Apache משפיעות על השילוב.
בודקים בסביבת ניסוי קובץ תקין, קובץ חסר ונקודת קצה שמחייבת הזדהות. אין להפוך שגיאה או תוכן פרטי לאובייקט ציבורי לשנה. באחסון מנוהל מבררים איזו שכבה אחראית לפני שמשנים ערך שעשוי להידרס או להיזנח.
מגדירים Nginx בלי להרחיב את הזכאות למטמון
משתמשים בנתיב ייעודי ונותנים תוקף ארוך רק לקבצים ציבוריים עם טביעה מתהליך הבנייה. הקטע שייך לבלוק server קיים ששורש המסמכים שלו כולל /assets/. בודקים קדימות locations מול הניתוב הנוכחי.
הדוגמה מגישה קבצים אמיתיים ואינה מעבירה קובץ חסר ליישום.
location ~ ^/assets/.+\.[a-f0-9]{8,}\.(css|js|mjs|png|jpg|jpeg|webp|avif|svg|woff2)$ {
try_files $uri =404;
add_header Cache-Control "public, max-age=31536000, immutable";
}היעדר always מכוון כדי לא לצרף את המדיניות לכל קוד שגיאה. בודקים ירושת add_header בגרסה המותקנת. הוספת כותרות במיקום פנימי יכולה להשפיע על כותרות אבטחה שירש; בגרסאות חדשות יש בקרות נוספות. שומרים את ההגנות הנדרשות ובודקים את התגובה הסופית.
מריצים nginx -t בהרשאות המתאימות לפני טעינה מחדש. זו בדיקת תחביר ולא אימות בטיחות המדיניות. בודקים במקור ודרך ה-CDN, שכן כלל ביניים יכול להחליף כותרת תקינה.
בודקים גרסאות תגובה ושכבות מטמון נוספות
Vary מציין אילו כותרות בקשה מבדילות בין ייצוגים. אם התוכן משתנה לפי קידוד, שפה או כותרת אחרת, המפתח חייב לשקף את ההבדל האמיתי. Vary: Cookie אינו פתרון כללי לתוכן אישי: הוא יכול ליצור גרסאות רבות ואינו מחליף מדיניות פרטית או עקיפה של מטמון משותף.
ל-CDN יש מפתח, תוקף ומנגנון מחיקה משלו. המחיקה בדרך כלל אינה מסירה עותקים מהדפדפן. לעדכון מידי של קובץ ציבורי, כתובת חדשה אמינה יותר ממחיקת הקצה בלבד. המדריך ל-CDN ולמטמון קצה מסביר את הקשר.
Service worker יכול ליירט בקשות ולנהל Cache Storage בנפרד ממטמון HTTP. קוד ישן או אסטרטגיית cache-first יכולים להסביר תוכן ישן גם כשהכותרות תקינות. בודקים את ה-worker ואת האחסון וחוזרים על האבחון תוך עקיפת השכבה. לא מוחקים ללא הבחנה נתונים לא מקוונים של משתמשים כחלק מעדכון שגרתי.
מאמתים ביקורים, עדכונים ומצבים פרטיים
פותחים Network בלי לסמן Disable cache. מבקרים כרגיל, חוזרים ובודקים כותרות ומידע העברה. תשובה מהזיכרון או מהדיסק שונה מתגובת רשת 304. רענון קשיח משנה במכוון התנהגות מטמון, ולכן אינו הבדיקה היחידה.
מחזיקים טבלת בדיקה קצרה של HTML ציבורי, קבצים עם טביעה, עמודים רגישים וכתובות חסרות. מתעדים הרשאת שמירה והתנהגות עדכון. כך מי שיתחזק בעתיד יבין כל כלל ויזהה שינויים רחבים שבדיקה של עמוד יחיד מפספסת.
משתמשים ב-GET אמיתי לבדיקת כותרות מהמסוף, משום ששרתים מסוימים מטפלים ב-HEAD אחרת.
curl -sS -D - -o /dev/null https://example.com/assets/app.8f3a1c2d.jsפורסים קובץ שהשתנה, מוודאים הפניה לשם החדש ומשאירים כרטיסייה ישנה לבדיקת יכולת שנטענת מאוחר. בודקים בנפרד ביקור אנונימי, מחובר ואחרי יציאה. עמוד פרטי אינו רשאי להיות התאמה משותפת, וקובץ חסר אינו אמור להחזיר HTML שמור.
רושמים את המדיניות והבדיקות ברשימת בדיקת הביצועים. בוחרים המשך במאגר מדריכי ביצועי השרת ומודדים מסלול של ביקור חוזר. המטרה היא שימוש בטוח ועדכון אמין, לא העלמת אזהרה במחיר תוכן ישן או חשוף.