Έχουμε γράψει για το CDN και για τα Core Web Vitals, αλλά όχι για το caching, και είναι παράλειψη. Γιατί από τα τρία, το caching είναι αυτό που δίνει τη μεγαλύτερη βελτίωση με τη λιγότερη δουλειά, και είναι επίσης αυτό που ρυθμίζεται λάθος πιο συχνά.
Ας ξεκαθαρίσουμε πρώτα τη διαφορά, γιατί τα μπερδεύουν συνεχώς. Το CDN μειώνει την απόσταση. Το caching μειώνει τη δουλειά. Το πρώτο φέρνει το αρχείο πιο κοντά στον επισκέπτη. Το δεύτερο αποφεύγει να ξαναφτιαχτεί το αρχείο από την αρχή. Είναι δύο διαφορετικά προβλήματα και θέλουν δύο διαφορετικές λύσεις, που συνήθως τις θέλετε και τις δύο.
Η μία εντολή που τα κάνει όλα
Δεν υπάρχουν δεκάδες ρυθμίσεις. Υπάρχει κυρίως μία κεφαλίδα, η Cache-Control, και δύο τιμές που πρέπει να ξέρετε.
Πριν από αυτές όμως, μια εκκρεμότητα τακτοποίησης. Θα βρείτε πολλούς οδηγούς να παραπέμπουν στο RFC 7234 για το caching. Έχει καταργηθεί. Το ισχύον πρότυπο είναι το RFC 9111, «HTTP Caching», του Ιουνίου 2022. Το γράφω γιατί, όπως και με το εργαλείο παραμέτρων του Search Console, είναι καλός δείκτης ηλικίας: αν το κείμενο που διαβάζετε παραπέμπει στο 7234, γράφτηκε πριν από τουλάχιστον τέσσερα χρόνια.
Τα δύο μόνο πράγματα που πρέπει να θυμάστε
Για τα στατικά αρχεία με μοναδικό όνομα, δηλαδή αυτά που ο μηχανισμός χτισίματος τα βγάζει ως style.a7f3d2.css και αλλάζει το όνομα κάθε φορά που αλλάζει το περιεχόμενο:
Cache-Control: max-age=31536000, immutable
Είναι ένα έτος σε δευτερόλεπτα, δηλαδή όπως το λέει το web.dev, «ουσιαστικά ισοδύναμο με για πάντα». Και δουλεύει χωρίς κίνδυνο, ακριβώς επειδή το όνομα αλλάζει όταν αλλάζει το περιεχόμενο. Δεν χρειάζεται ποτέ να «καθαρίσετε» τίποτα: το καινούριο αρχείο έχει άλλο όνομα, οπότε ο browser το ζητά ούτως ή άλλως.
Για τις σελίδες HTML, το ακριβώς αντίθετο:
Cache-Control: max-age=0, must-revalidate, public
Δηλαδή κράτα αντίγραφο, αλλά ρώτα με κάθε φορά πριν το χρησιμοποιήσεις. Γιατί η διεύθυνση της σελίδας σας δεν αλλάζει όνομα όταν αλλάζετε ένα κείμενο, οπότε δεν υπάρχει άλλος τρόπος να μάθει ο browser ότι κάτι έγινε.
Αυτά τα δύο είναι το ενενήντα τοις εκατό της δουλειάς. Τα υπόλοιπα είναι λεπτομέρειες.
Το όνομα που παραπλανά τους πάντες
Το no-cache δεν σημαίνει «μην αποθηκεύεις». Το λέει και η ίδια η ομάδα του Chrome, με ασυνήθιστη ειλικρίνεια για τεκμηρίωση: «το no-cache είναι μπερδεμένο όνομα, γιατί θα μπορούσε να ερμηνευτεί ως μην αποθηκεύσεις ποτέ αυτό το αρχείο, ενώ δεν είναι αυτό».
Σημαίνει: αποθήκευσε το, αλλά ρώτα πριν το χρησιμοποιήσεις. Είναι ουσιαστικά το ίδιο με το max-age=0, must-revalidate που είδαμε παραπάνω.
Αυτό που σημαίνει «μην αποθηκεύεις» είναι το no-store, και είναι πολύ πιο βαρύ. Το χρησιμοποιείτε σε σελίδες με προσωπικά δεδομένα, σε πίνακες ελέγχου μετά από σύνδεση, σε ό,τι δεν πρέπει να μείνει στον υπολογιστή του χρήστη. Όχι στην αρχική σας.
Η σύγχυση των δύο κοστίζει και προς τις δύο κατευθύνσεις. Άλλοι βάζουν no-store παντού και σκοτώνουν κάθε βελτίωση, άλλοι βάζουν no-cache σε αρχεία που θα μπορούσαν να μείνουν έναν χρόνο.
Πόσοι το κάνουν σωστά; Η ειλικρινής απάντηση
Θα ήθελα να σας δώσω ποσοστό, και έψαξα. Δεν υπάρχει.
Το Web Almanac, που είναι η μεγαλύτερη ετήσια μέτρηση του ιστού, δεν έχει κεφάλαιο για caching ούτε στην έκδοση του 2024 ούτε σε αυτήν του 2025. Το τελευταίο ήταν γύρω στο 2021. Θα βρείτε κείμενα να λένε «μόνο το 38% ρυθμίζει σωστά τις κεφαλίδες». Δεν εντόπισα τέτοιο στοιχείο πουθενά.
Δύο σχετικά νούμερα υπάρχουν όντως, από άλλα κεφάλαια της μέτρησης του 2024: το 21% των ιστότοπων χρησιμοποιεί Cache-Control: no-store, και το 25% των κινητών ιστότοπων δεν χρησιμοποιεί καθόλου cache. Το πρώτο είναι ενδιαφέρον γιατί το no-store έχει και άλλη παρενέργεια, εμποδίζει τη σελίδα να μπει στη μνήμη πίσω και εμπρός του browser, οπότε το κουμπί «πίσω» ξαναφορτώνει τα πάντα.
Δύο περιστατικά από το δικό μας site
Επειδή μέχρι εδώ μιλήσαμε θεωρητικά, ας γίνουμε συγκεκριμένοι με δικά μας λάθη.
Το πρώτο ήταν δικό μας, και το φτιάξαμε. Το mslogic.gr έστελνε για τις σελίδες HTML max-age=3600, δηλαδή μία ώρα. Ακούγεται λογικό μέχρι να σκεφτείτε τι σημαίνει: διορθώνατε ένα κείμενο και ο επισκέπτης που είχε περάσει πριν από σαράντα λεπτά έβλεπε ακόμη το παλιό. Το κατεβάσαμε σε μηδέν με υποχρεωτική επαλήθευση, που είναι ακριβώς η σύσταση που είδαμε παραπάνω. Τα στατικά αρχεία έμειναν στο ένα έτος, γιατί είναι fingerprinted.
Το δεύτερο ήταν πιο ύπουλο, και μας ξεγέλασε. Μετά από ένα ανέβασμα, η σελίδα εξακολουθούσε να δείχνει την προηγούμενη έκδοση, παρότι η κεφαλίδα έλεγε μηδέν. Την ίδια στιγμή, με μια παράμετρο στο τέλος της διεύθυνσης, γύριζε αμέσως η καινούρια. Δηλαδή δεν έφταιγε η ρύθμιση, υπήρχε ενδιάμεσο αντίγραφο στον proxy του server που δεν είχε ανανεωθεί.
Το γράφω γιατί έχει δύο πρακτικές συνέπειες που ίσως σας αφορούν. Όταν ελέγχετε μετά από ανέβασμα, βάλτε ένα ?v=1 στο τέλος της διεύθυνσης, αλλιώς μπορεί να κοιτάτε αντίγραφο και να νομίζετε ότι κάτι πήγε στραβά. Και αν κάποιος αυτόματος έλεγχος τρέξει αμέσως μετά, μπορεί να σας πει ότι λείπει κάτι που υπάρχει.
Η παγίδα που σβήνει τις κεφαλίδες ασφαλείας
Και μια προειδοποίηση για όποιον σκεφτεί να τα ρυθμίσει μόνος του στον nginx, γιατί την πατήσαμε παρά τρίχα.
Η προφανής κίνηση είναι να φτιάξετε ένα location block για τα αρχεία HTML και να βάλετε μέσα το add_header με το caching. Μην το κάνετε έτσι. Στον nginx, όταν ένα location ορίσει έστω ένα add_header, χάνει όλα τα add_header που κληρονομεί από το επίπεδο πάνω του.
Καταλαβαίνετε τι σημαίνει αυτό. Οι σελίδες HTML, δηλαδή ακριβώς αυτές που χρειάζονται το Content-Security-Policy και τις υπόλοιπες κεφαλίδες ασφαλείας, θα έμεναν χωρίς αυτές. Θα κερδίζατε μερικά δευτερόλεπτα και θα χάνατε τη θωράκιση, χωρίς καμία προειδοποίηση πουθενά.
Η σωστή μορφή είναι αντίστροφη: σύντομο cache ως γενικός κανόνας στο επίπεδο του server, και εξαίρεση με μεγάλη διάρκεια μόνο για τα στατικά αρχεία.
Εμείς τελικά δεν χρειάστηκε να το αγγίξουμε καθόλου, γιατί για το Cache-Control αποδείχθηκε ότι υπεύθυνο ήταν το .htaccess και όχι ο nginx. Το βρήκαμε όμως κοιτάζοντας τις πραγματικές κεφαλίδες που φτάνουν, όχι διαβάζοντας τα αρχεία ρυθμίσεων.
Και το πιο σύγχρονο κομμάτι
Υπάρχει και μια τρίτη επιλογή που δεν την ξέρουν πολλοί: το stale-while-revalidate.
Λέει στον browser: δείξε αμέσως το παλιό αντίγραφο, και ταυτόχρονα πήγαινε φέρε το καινούριο στο παρασκήνιο. Ο επισκέπτης βλέπει κάτι μέσα σε ελάχιστο χρόνο, και η επόμενη φόρτωση είναι ενημερωμένη.
Είναι εξαιρετικό για περιεχόμενο που αλλάζει, αλλά όχι κάθε λεπτό. Λίστα προϊόντων, σελίδα κατηγορίας, αρχική blog. Δεν είναι για τιμές που αλλάζουν την ώρα που μιλάμε, ούτε για απόθεμα.
Τι κρατάτε από όλα αυτά
Αν έχετε στατικό site, το πιθανότερο είναι ότι σας λείπει μόνο η σωστή τιμή στα δύο πράγματα που είπαμε, και είναι δουλειά μισής ώρας. Αν έχετε WordPress, το θέμα είναι μεγαλύτερο και έχει και άλλα επίπεδα, γιατί εκεί κάθε σελίδα χτίζεται από την αρχή σε κάθε επίσκεψη αν δεν το εμποδίσει κάποιος.
Το κοινό και στις δύο περιπτώσεις είναι ότι δεν αγοράζεται. Δεν υπάρχει πρόσθετο που να το κάνει σωστά χωρίς να ξέρει κάποιος τι θέλει να πετύχει. Και το χειρότερο λάθος δεν είναι να μην έχετε caching, είναι να έχετε λάθος caching: να σερβίρετε παλιές τιμές σε πελάτη, ή να κρατάτε στον υπολογιστή του δεδομένα που δεν έπρεπε.
Κι έτσι επιστρέφουμε στη διάκριση της αρχής. Το CDN φέρνει το αρχείο πιο κοντά, το caching το φτιάχνει λιγότερες φορές. Αν θέλετε να δούμε τι στέλνει σήμερα ο δικός σας server και τι θα έπρεπε, επικοινωνήστε μαζί μου.