Τα βασικά της προσωρινής αποθήκευσης πελατών με ξεκάθαρες λέξεις και παραδείγματα. Τελευταία τροποποίηση, Etag, Expires, Cache-Control: max-age και άλλες κεφαλίδες. Βέλτιστες πρακτικές αποθήκευσης στην κρυφή μνήμη Απλή αποθήκευση ETag στην προσωρινή μνήμη

Συμπεριλαμβάνοντας εξωτερικό CSS και Javascript, θέλουμε να μειώσουμε στο ελάχιστο τα περιττά αιτήματα HTTP.

Για το σκοπό αυτό, τα αρχεία .js και .css εξυπηρετούνται με κεφαλίδες που εξασφαλίζουν αξιόπιστη προσωρινή αποθήκευση.

Τι κάνετε όμως όταν ένα από αυτά τα αρχεία αλλάζει κατά την ανάπτυξη; Όλοι οι χρήστες το έχουν στην κρυφή μνήμη παλιά εκδοχή- έως ότου η προσωρινή μνήμη είναι ξεπερασμένη, θα υπάρχουν πολλά παράπονα σχετικά με τη διακοπή της ενοποίησης των εξαρτημάτων διακομιστή και πελάτη.

Η σωστή αποθήκευση στην προσωρινή μνήμη και η σωστή δημιουργία εκδόσεων εξαλείφει αυτό το πρόβλημα εντελώς και παρέχει αξιόπιστο, διαφανή συγχρονισμό των εκδόσεων στυλ/σεναρίου.

Απλή αποθήκευση ETag στην κρυφή μνήμη

Ο απλούστερος τρόπος αποθήκευσης στατικών πόρων είναι να χρησιμοποιήσετε το ETag.

Αρκεί να ενεργοποιήσετε την κατάλληλη ρύθμιση διακομιστή (για τον Apache είναι ενεργοποιημένη από προεπιλογή) - και για κάθε αρχείο στις κεφαλίδες θα δίνεται ένα ETag - ένας κατακερματισμός που εξαρτάται από τον χρόνο ενημέρωσης, το μέγεθος του αρχείου και (με βάση το inode συστήματα αρχείων) inode.

Το πρόγραμμα περιήγησης αποθηκεύει προσωρινά ένα τέτοιο αρχείο και, σε επόμενα αιτήματα, καθορίζει μια κεφαλίδα If-None-Match με το ETag του αποθηκευμένου εγγράφου. Έχοντας λάβει μια τέτοια κεφαλίδα, ο διακομιστής μπορεί να απαντήσει με τον κωδικό 304 - και στη συνέχεια το έγγραφο θα ληφθεί από την προσωρινή μνήμη.

Μοιάζει με αυτό:

Πρώτο αίτημα στον διακομιστή (καθαρισμός της προσωρινής μνήμης) GET /misc/pack.js HTTP/1.1 Host: website

Γενικά, το πρόγραμμα περιήγησης συνήθως προσθέτει μια δέσμη κεφαλίδων όπως User-Agent, Accept, κ.λπ. Κόβονται για συντομία.

Απόκριση διακομιστή Ο διακομιστής απαντά με ένα έγγραφο με κωδικό 200 και ETag: HTTP/1.x 200 OK Περιεχόμενο-Κωδικοποίηση: gzip Περιεχόμενο-Τύπος: text/javascript; charset=utf-8 Etag: "3272221997" Accept-Ranses: bytes Content-Length: 23321 Ημερομηνία: Παρασκευή, 02 Μαΐου 2008 17:22:46 GMT Διακομιστής: lighttpd Επόμενο αίτημα προγράμματος περιήγησης Στο επόμενο αίτημα, το πρόγραμμα περιήγησης προσθέτει If-None -Αντιστοίχιση: (αποθηκευμένη στην προσωρινή μνήμη ETag): GET /misc/pack.js HTTP/1.1 Κεντρικός υπολογιστής: ιστότοπος If-None-Match: "453700005" Απόκριση διακομιστή Ο διακομιστής φαίνεται - ναι, το έγγραφο δεν έχει αλλάξει. Αυτό σημαίνει ότι μπορείτε να εκδώσετε έναν κωδικό 304 και να μην στείλετε ξανά το έγγραφο. HTTP/1.x 304 Μη τροποποιημένο περιεχόμενο-Κωδικοποίηση: gzip Etag: "453700005" Τύπος περιεχομένου: text/javascript; charset=utf-8 Accept-Ranges: bytes Ημερομηνία: Τρίτη, 15 Απριλίου 2008 10:17:11 GMT

Εναλλακτική επιλογη- εάν το έγγραφο έχει αλλάξει, τότε ο διακομιστής στέλνει απλώς 200 με το νέο ETag.

Ο συνδυασμός Last-Modified + If-Modified-Since λειτουργεί με παρόμοιο τρόπο:

  • ο διακομιστής στέλνει την ημερομηνία της τελευταίας τροποποίησης στην κεφαλίδα Last-Modified (αντί για ETag)
  • το πρόγραμμα περιήγησης αποθηκεύει προσωρινά το έγγραφο και την επόμενη φορά που υποβάλλεται αίτημα για το ίδιο έγγραφο, στέλνει την ημερομηνία της κρυφής έκδοσης στην κεφαλίδα If-Modified-Since (αντί για If-None-Match)
  • ο διακομιστής ελέγχει τις ημερομηνίες και εάν το έγγραφο δεν έχει αλλάξει, στέλνει μόνο τον κωδικό 304, χωρίς το περιεχόμενο.
  • Αυτές οι μέθοδοι λειτουργούν αξιόπιστα και καλά, αλλά το πρόγραμμα περιήγησης πρέπει ακόμα να υποβάλει αίτημα για κάθε σενάριο ή στυλ.

    Έξυπνη προσωρινή αποθήκευση. Εκδόσεις

    Η γενική προσέγγιση για την έκδοση - με λίγα λόγια:

  • Η έκδοση (ή η ημερομηνία τροποποίησης) προστίθεται σε όλα τα σενάρια. Για παράδειγμα, το http://site/my.js θα γίνει http://site/my.v1.2.js
  • Όλα τα σενάρια αποθηκεύονται προσωρινά από το πρόγραμμα περιήγησης
  • Κατά την ενημέρωση του σεναρίου, η έκδοση αλλάζει σε νέα: http://site/my.v2.0.js
  • Η διεύθυνση έχει αλλάξει, επομένως το πρόγραμμα περιήγησης θα ζητήσει και θα αποθηκεύσει ξανά το αρχείο στην προσωρινή μνήμη
  • Η παλιά έκδοση 1.2 θα πέσει σταδιακά από την προσωρινή μνήμη
  • Σκληρή προσωρινή αποθήκευση

    Σκληρή προσωρινή αποθήκευση- ένα είδος βαριοπούλας που καρφώνει εντελώς αιτήματα στον διακομιστή για αποθηκευμένα έγγραφα.

    Για να το κάνετε αυτό, απλώς προσθέστε τις κεφαλίδες Expires και Cache-Control: max-age.

    Για παράδειγμα, για cache για 365 ημέρες σε PHP:

    Header("Expires: ".gmdate("D, d M Y H:i:s", time()+86400*365)." GMT"); header("Cache-Control: max-age="+86400*365);

    Ή μπορείτε να αποθηκεύσετε το περιεχόμενο μόνιμα χρησιμοποιώντας το mod_header στο Apache:

    Έχοντας λάβει τέτοιες κεφαλίδες, το πρόγραμμα περιήγησης αποθηκεύει σκληρά το έγγραφο για μεγάλο χρονικό διάστημα. Όλη η περαιτέρω πρόσβαση στο έγγραφο θα εξυπηρετείται απευθείας από την προσωρινή μνήμη του προγράμματος περιήγησης, χωρίς να επικοινωνήσετε με τον διακομιστή.

    Τα περισσότερα προγράμματα περιήγησης (Opera, Internet Explorer 6+, Safari) ΜΗΝ αποθηκεύετε στην κρυφή μνήμη έγγραφα εάν υπάρχει ερωτηματικό στη διεύθυνση, γιατί θεωρούνται δυναμικά.

    Γι' αυτό προσθέτουμε την έκδοση στο όνομα του αρχείου. Φυσικά, με τέτοιες διευθύνσεις πρέπει να χρησιμοποιήσετε μια λύση όπως το mod_rewrite, θα το δούμε αργότερα στο άρθρο.

    P.S Αλλά ο Firefox αποθηκεύει τις διευθύνσεις με ερωτηματικά...

    Αυτόματη ανάλυση ονόματος

    Ας δούμε πώς μπορείτε να αλλάζετε αυτόματα και με διαφάνεια τις εκδόσεις χωρίς να μετονομάσετε τα ίδια τα αρχεία.

    Όνομα με έκδοση -> Αρχείο

    Το πιο απλό πράγμα είναι να μετατρέψετε το όνομα με την έκδοση στο αρχικό όνομα αρχείου.

    Σε επίπεδο Apache αυτό μπορεί να γίνει με mod_rewrite:

    RewriteEngine στο RewriteRule ^/(.*\.)v+\.(css|js|gif|png|jpg)$ /$1$2 [L]

    Αυτός ο κανόνας επεξεργάζεται όλα τα αρχεία css/js/gif/png/jpg, αφαιρώντας την έκδοση από το όνομα.

    Για παράδειγμα:

    /images/logo.v2.gif -> /images/logo.gif
    /css/style.v1.27.css -> /css/style.css
    /javascript/script.v6.js -> /javascript/script.js

    Αλλά εκτός από την αποκοπή της έκδοσης, πρέπει επίσης να προσθέσετε κεφαλίδες σκληρής προσωρινής αποθήκευσης στα αρχεία. Οι οδηγίες mod_header χρησιμοποιούνται για αυτό:

    Προσθήκη κεφαλίδας "Λήγει" "Δευτ., 28 Ιουλίου 2014 23:30:00 GMT" Προσθήκη κεφαλίδας "Cache-Control" "max-age=315360000"

    Και όλα μαζί υλοποιεί την ακόλουθη διαμόρφωση Apache:

    Το RewriteEngine on # καταργεί την έκδοση και ταυτόχρονα ορίζει τη μεταβλητή ότι το αρχείο έχει έκδοση RewriteRule ^/(.*\.)v+\.(css|js|gif|png|jpg)$ /$1$2 # σκληρή κρυφή μνήμη αρχεία έκδοσης Επικεφαλίδα προσθήκη "Λήγει" "Δευτ., 28 Ιουλίου 2014 23:30:00 GMT" env=VERSIONED_FILE Κεφαλίδα προσθήκη "Cache-Control" "max-age=315360000" env=VERSIONED_FILE

    Λόγω του τρόπου με τον οποίο λειτουργεί η ενότητα mod_rewrite, το RewriteRule πρέπει να τοποθετηθεί στο main αρχείο ρυθμίσεων httpd.conf ή αρχεία που περιλαμβάνονται, αλλά ποτέ σε .htaccess, διαφορετικά οι εντολές Header θα εκτελεστούν πρώτα, πριν οριστεί η μεταβλητή VERSIONED_FILE.

    Οι οδηγίες κεφαλίδας μπορούν να βρίσκονται οπουδήποτε, ακόμη και σε .htaccess - δεν πειράζει.

    Αυτόματη προσθήκη έκδοσης στο όνομα αρχείου στη σελίδα HTML

    Το πώς να βάλετε την έκδοση στο όνομα του σεναρίου εξαρτάται από το σύστημα προτύπων σας και, γενικά, από τον τρόπο που προσθέτετε σενάρια (στυλ, κ.λπ.).

    Για παράδειγμα, όταν χρησιμοποιείτε την ημερομηνία τροποποίησης ως έκδοση και τη μηχανή προτύπων Smarty, οι σύνδεσμοι μπορούν να οριστούν ως εξής:

    Η συνάρτηση έκδοσης προσθέτει την έκδοση:

    Λειτουργία smarty_version($args)( $stat = stat($GLOBALS["config"]["site_root"].$args["src"]); $version = $stat["mtime"]; echo preg_replace("! \.(+?)$!", ".v$version.\$1", $args["src"]); )

    Αποτέλεσμα στη σελίδα:

    Βελτιστοποίηση

    Για να αποφύγετε περιττές κλήσεις στατιστικών στοιχείων, μπορείτε να αποθηκεύσετε έναν πίνακα με μια λίστα με τις τρέχουσες εκδόσεις σε μια ξεχωριστή μεταβλητή

    $versions["css"] = πίνακας("group.css" => "1.1", "other.css" => "3.0", )

    Σε αυτήν την περίπτωση, η τρέχουσα έκδοση από τον πίνακα απλώς αντικαθίσταται στο HTML.

    Μπορείτε να διασχίσετε και τις δύο προσεγγίσεις και κατά την ανάπτυξη να δημιουργήσετε μια έκδοση κατά ημερομηνία τροποποίησης - για συνάφεια και στην παραγωγή - μια έκδοση από μια συστοιχία, για απόδοση.

    Εφαρμογή

    Αυτή η μέθοδος προσωρινής αποθήκευσης λειτουργεί παντού, συμπεριλαμβανομένων Javascript, CSS, εικόνων, ταινιών Flash κ.λπ.

    Είναι χρήσιμο κάθε φορά που αλλάζει το έγγραφο, αλλά το πρόγραμμα περιήγησης πρέπει πάντα να έχει την τρέχουσα, ενημερωμένη έκδοση.

    Η κρυφή μνήμη διαδραματίζει σημαντικό ρόλο στη λειτουργία σχεδόν οποιασδήποτε διαδικτυακής εφαρμογής σε επίπεδο εργασίας με βάσεις δεδομένων, διακομιστές ιστού και επίσης στον πελάτη.

    Σε αυτό το άρθρο θα προσπαθήσουμε να κατανοήσουμε την προσωρινή αποθήκευση του πελάτη. Συγκεκριμένα, θα εξετάσουμε ποιες κεφαλίδες HTTP χρησιμοποιούνται από προγράμματα περιήγησης και διακομιστές ιστού και τι σημαίνουν.

    Αλλά πρώτα, ας μάθουμε γιατί χρειάζεται καθόλου η προσωρινή αποθήκευση από την πλευρά του πελάτη; .

    Οι ιστοσελίδες αποτελούνται από πολλές διάφορα στοιχεία: εικόνες, αρχεία css και js κ.λπ. Μερικά από αυτά τα στοιχεία χρησιμοποιούνται σε πολλές (πολλές) σελίδες του ιστότοπου. Η προσωρινή αποθήκευση από την πλευρά του πελάτη αναφέρεται στη δυνατότητα των προγραμμάτων περιήγησης να αποθηκεύουν αντίγραφα αρχείων (απαντήσεις διακομιστή) ώστε να μην τα κατεβάζουν ξανά. Αυτό σας επιτρέπει να επιταχύνετε σημαντικά την επαναφόρτωση της σελίδας, να εξοικονομήσετε κίνηση και επίσης να μειώσετε το φόρτο στον διακομιστή.

    Υπάρχουν πολλές διαφορετικές κεφαλίδες HTTP για τον έλεγχο των διαδικασιών προσωρινής αποθήκευσης από την πλευρά του πελάτη. Ας μιλήσουμε για καθένα από αυτά.

    Επικεφαλίδες Http για τον έλεγχο της προσωρινής αποθήκευσης του πελάτη

    Αρχικά, ας δούμε πώς αλληλεπιδρούν ο διακομιστής και το πρόγραμμα περιήγησης απουσία οποιασδήποτε προσωρινής αποθήκευσης. Για μια σαφή κατανόηση, προσπάθησα να φανταστώ και να οπτικοποιήσω τη διαδικασία επικοινωνίας μεταξύ τους με τη μορφή συνομιλίας κειμένου. Φανταστείτε για λίγα λεπτά ότι ο διακομιστής και το πρόγραμμα περιήγησης είναι άτομα που αλληλογραφούν μεταξύ τους :)

    Χωρίς προσωρινή μνήμη (ελλείψει προσωρινής αποθήκευσης κεφαλίδων http)

    Όπως μπορούμε να δούμε, κάθε φορά που εμφανίζεται η εικόνα cat.png, το πρόγραμμα περιήγησης θα την κατεβάσει ξανά από τον διακομιστή. Νομίζω ότι δεν χρειάζεται να εξηγήσω ότι αυτό είναι αργό και αναποτελεσματικό.

    Κεφαλίδα απόκρισης τελευταίας τροποποίησης και κεφαλίδα αιτήματος if-Modified-Since.

    Η ιδέα είναι ότι ο διακομιστής προσθέτει μια κεφαλίδα τελευταίας τροποποίησης στο αρχείο (απόκριση) που δίνει στο πρόγραμμα περιήγησης.

    Το πρόγραμμα περιήγησης γνωρίζει πλέον ότι το αρχείο δημιουργήθηκε (ή τροποποιήθηκε) την 1η Δεκεμβρίου 2014. Την επόμενη φορά που το πρόγραμμα περιήγησης θα χρειαστεί το ίδιο αρχείο, θα στείλει ένα αίτημα με μια κεφαλίδα if-Modified-Since.

    Εάν το αρχείο δεν έχει τροποποιηθεί, ο διακομιστής στέλνει μια κενή απάντηση στο πρόγραμμα περιήγησης με κατάσταση 304 (Not Modified). Σε αυτήν την περίπτωση, το πρόγραμμα περιήγησης γνωρίζει ότι το αρχείο δεν έχει ενημερωθεί και μπορεί να εμφανίσει το αντίγραφο που αποθηκεύτηκε την τελευταία φορά.

    Έτσι, χρησιμοποιώντας το Last-modified εξοικονομούμε κατά τη φόρτωση μεγάλο αρχείο, αποχωρώντας με μια κενή γρήγορη απάντηση από τον διακομιστή.

    Κεφαλίδα απόκρισης etag και κεφαλίδα αιτήματος If-None-Match.

    Η αρχή λειτουργίας του Etag είναι πολύ παρόμοια με το Last-modified, αλλά, σε αντίθεση με αυτό, δεν συνδέεται με το χρόνο. Ο χρόνος είναι κάτι σχετικό.

    Η ιδέα είναι ότι όταν δημιουργείται και κάθε φορά που αλλάζει, ο διακομιστής προσθέτει ετικέτα στο αρχείο με μια ειδική ετικέτα που ονομάζεται ETag και προσθέτει επίσης μια κεφαλίδα στο αρχείο (απόκριση) που δίνει στο πρόγραμμα περιήγησης:

    ETag: "686897696a7c876b7e"

    Τώρα το πρόγραμμα περιήγησης γνωρίζει ότι το τρέχον αρχείο έκδοσης έχει ETag ίσο με "686897696a7c876b7e". Την επόμενη φορά που το πρόγραμμα περιήγησης θα χρειαστεί το ίδιο αρχείο, θα στείλει ένα αίτημα με την κεφαλίδα If-None-Match: "686897696a7c876b7e" .

    Αν-καμία-ταίριασμα: "686897696a7c876b7e"

    Ο διακομιστής μπορεί να συγκρίνει τις ετικέτες και, εάν το αρχείο δεν έχει τροποποιηθεί, να στείλει μια κενή απάντηση στο πρόγραμμα περιήγησης με κατάσταση 304 (Not Modified). Όπως και με το Last-modified, το πρόγραμμα περιήγησης θα καταλάβει ότι το αρχείο δεν έχει ενημερωθεί και θα μπορεί να εμφανίσει ένα αντίγραφο από τη μνήμη cache.

    Ο τίτλος έληξε

    Η αρχή λειτουργίας αυτής της κεφαλίδας διαφέρει από το Etag και το Last-modified που περιγράφονται παραπάνω. Χρησιμοποιώντας το Expired, προσδιορίζεται η "ημερομηνία λήξης" ("περίοδος συνάφειας") του αρχείου. Εκείνοι. Κατά την πρώτη φόρτωση, ο διακομιστής ενημερώνει το πρόγραμμα περιήγησης ότι δεν σκοπεύει να αλλάξει το αρχείο μέχρι την ημερομηνία που καθορίζεται στο Expired:

    Την επόμενη φορά, το πρόγραμμα περιήγησης, γνωρίζοντας ότι η "ημερομηνία λήξης" δεν έχει φτάσει ακόμη, δεν θα προσπαθήσει καν να υποβάλει αίτημα στον διακομιστή και θα εμφανίσει το αρχείο από την προσωρινή μνήμη.

    Αυτός ο τύπος κρυφής μνήμης είναι ιδιαίτερα σημαντικός για εικονογραφήσεις για άρθρα, εικονίδια, favicons, ορισμένα αρχεία css και js κ.λπ.

    Κεφαλίδα ελέγχου προσωρινής μνήμης με οδηγία max-age.

    Η αρχή λειτουργίας του Cache-Control: το max-age είναι πολύ παρόμοιο με το Expired. Εδώ προσδιορίζεται και η «ημερομηνία λήξης» του αρχείου, αλλά ορίζεται σε δευτερόλεπτα και δεν συνδέεται με συγκεκριμένο χρόνο, κάτι που είναι πολύ πιο βολικό στις περισσότερες περιπτώσεις.

    Για αναφορά:

    • 1 ημέρα = 86400 δευτερόλεπτα
    • 1 εβδομάδα = 604800 δευτερόλεπτα
    • 1 μήνας = 2629000 δευτερόλεπτα
    • 1 έτος = 31536000 δευτερόλεπτα

    Π.χ:

    Cache-Control: max-age=2629000;

    Η κεφαλίδα Cache-Control έχει και άλλες οδηγίες εκτός από το max-age. Ας ρίξουμε μια γρήγορη ματιά στα πιο δημοφιλή:

    δημόσιο
    Το γεγονός είναι ότι τα αιτήματα μπορούν να αποθηκευτούν στην κρυφή μνήμη όχι μόνο από τον τελικό πελάτη (πρόγραμμα περιήγησης) του χρήστη, αλλά και από διάφορους ενδιάμεσους διακομιστές, δίκτυα CDN κ.λπ. Έτσι, η δημόσια οδηγία επιτρέπει σε οποιονδήποτε διακομιστή μεσολάβησης να εκτελεί προσωρινή αποθήκευση ακριβώς όπως ένα πρόγραμμα περιήγησης.

    ιδιωτικός
    Η οδηγία αναφέρει ότι αυτό το αρχείο(απόκριση διακομιστή) είναι συγκεκριμένη για τον τελικό χρήστη και δεν θα πρέπει να αποθηκεύεται προσωρινά από διάφορους ενδιάμεσους διακομιστές. Ταυτόχρονα, επιτρέπει την προσωρινή αποθήκευση στον τελικό πελάτη (πρόγραμμα περιήγησης χρήστη). Για παράδειγμα, αυτό είναι σχετικό με εσωτερικές σελίδες προφίλ χρήστη, αιτήματα σε μια περίοδο λειτουργίας κ.λπ.

    Σας επιτρέπει να καθορίσετε ότι ο πελάτης θα πρέπει να υποβάλλει ένα αίτημα στον διακομιστή κάθε φορά. Μερικές φορές χρησιμοποιείται με την κεφαλίδα Etag που περιγράφεται παραπάνω.

    χωρίς κατάστημα
    Καθοδηγεί τον πελάτη ότι δεν πρέπει να διατηρεί αντίγραφο του αιτήματος ή μέρη του αιτήματος σε καμία περίπτωση. Αυτή είναι η πιο αυστηρή κεφαλίδα, παρακάμπτοντας τυχόν κρυφές μνήμες. Εφευρέθηκε ειδικά για την εργασία με εμπιστευτικές πληροφορίες.

    πρέπει να επανεπικυρωθεί
    Αυτή η οδηγία δίνει οδηγίες στο πρόγραμμα περιήγησης να υποβάλει υποχρεωτικό αίτημα στον διακομιστή για την εκ νέου επικύρωση του περιεχομένου (για παράδειγμα, εάν χρησιμοποιείτε eTag). Το γεγονός είναι ότι το http σε μια συγκεκριμένη διαμόρφωση επιτρέπει στην κρυφή μνήμη να αποθηκεύει περιεχόμενο που είναι ήδη ξεπερασμένο. Το must-revalidate υποχρεώνει το πρόγραμμα περιήγησης να ελέγχει τη φρεσκάδα του περιεχομένου υπό οποιεσδήποτε συνθήκες υποβάλλοντας ένα αίτημα στον διακομιστή.

    proxy-revalidate
    Αυτό είναι το ίδιο με το must-revalidate, αλλά ισχύει μόνο για την προσωρινή αποθήκευση μεσολάβησης.

    s-maxage
    Πρακτικά δεν διαφέρει από το max-age , εκτός από το ότι αυτή η οδηγία λαμβάνεται υπόψη μόνο από την κρυφή μνήμη διαφορετικών διακομιστών μεσολάβησης, αλλά όχι από το ίδιο το πρόγραμμα περιήγησης του χρήστη. Το γράμμα «s -» προέρχεται από τη λέξη «shared» (π.χ. CDN). Αυτή η οδηγία προορίζεται ειδικά για CDN και άλλες ενδιάμεσες κρυφές μνήμες. Ο καθορισμός της παρακάμπτει τις τιμές της οδηγίας max-age και της κεφαλίδας Expired. Ωστόσο, εάν δεν δημιουργείτε δίκτυα CDN, τότε είναι απίθανο να χρειαστείτε ποτέ s-maxage.

    Πώς μπορώ να δω ποιες κεφαλίδες χρησιμοποιούνται σε έναν ιστότοπο;

    Μπορείτε να προβάλετε τις κεφαλίδες αιτημάτων http και τις κεφαλίδες απόκρισης στο πρόγραμμα εντοπισμού σφαλμάτων του αγαπημένου σας προγράμματος περιήγησης. Ακολουθεί ένα παράδειγμα για το πώς φαίνεται στο Chrome:

    Το ίδιο πράγμα μπορεί να δει κανείς σε οποιοδήποτε πρόγραμμα περιήγησης ή http sniffer που σέβεται τον εαυτό του.

    Ρύθμιση προσωρινής αποθήκευσης σε Apache και Nginx

    Δεν θα επαναλάβουμε την τεκμηρίωση για τη ρύθμιση δημοφιλών διακομιστών. Μπορείτε πάντα να το παρακολουθήσετε και. Παρακάτω θα δώσουμε μερικά πραγματικά παραδείγματα για να δείξουμε πώς μοιάζουν τα αρχεία διαμόρφωσης.

    Παράδειγμα Διαμορφώσεις Apacheγια έλεγχο Λήγει

    Ορίζουμε διαφορετικές «ημερομηνίες λήξης». διάφοροι τύποιαρχεία. Ένας χρόνος για εικόνες, ένας μήνας για σενάρια, στυλ, pdf και εικονίδια. Για όλα τα άλλα - 2 ημέρες.

    ExpiresActive On ExpiresByType εικόνα/jpg "πρόσβαση συν 1 έτος" ExpiresByType εικόνα/jpeg "πρόσβαση συν 1 έτος" ExpiresByType εικόνα/gif "πρόσβαση συν 1 έτος" ExpiresByType εικόνα/png "πρόσβαση συν 1 έτος" ExpiresByType συν 1 έτος μήνα" ExpiresByType εφαρμογή/pdf "πρόσβαση συν 1 μήνα" ExpiresByType κείμενο/x-javascript "πρόσβαση συν 1 μήνα" ExpiresByType εικόνα/εικονίδιο x "πρόσβαση συν 1 έτος" ExpiresΠροεπιλογή "πρόσβαση συν 2 ημέρες"

    Παράδειγμα διαμόρφωσης Nginx για τον έλεγχο του Expires

    Ορίζουμε διαφορετικές «ημερομηνίες λήξης» για διαφορετικούς τύπους αρχείων. Μια εβδομάδα για εικόνες, μια μέρα για στυλ και σενάρια.

    Διακομιστής ( #... τοποθεσία ~* \.(gif|ico|jpe?g|png)(\?+)?$ ( λήγει 1w; ) τοποθεσία ~* \.(css|js)$ ( λήγει 1η; ) #...)

    Παράδειγμα διαμόρφωσης Apache για Cache-Control (max-age και public/private/no-cache) Σύνολο κεφαλίδων Cache-Control "max-age=2592000, public" Σύνολο κεφαλίδων Cache-Control "max-age=88000, private, must- revalidate" Σύνολο κεφαλίδων Cache-Control "private, no-store, no-cache, must-revalidate, no-transform, max-age=0" Σύνολο κεφαλίδων Pragma "no-cache" Παράδειγμα διαμόρφωσης Nginx για διακομιστή στατικών αρχείων Cache-control ( #... τοποθεσία ~* \.(?:ico|css|js|gif|jpe?g|png)$ ( add_header Cache-Control "max-age=88000, public"; ) #... ) Σε συμπέρασμα

    "Αποθηκεύστε προσωρινά όλα όσα μπορούν να αποθηκευτούν στην προσωρινή μνήμη" είναι ένα καλό σύνθημα για έναν προγραμματιστή ιστού. Μερικές φορές μπορείτε να αφιερώσετε λίγες μόνο ώρες στη διαμόρφωση και ταυτόχρονα να βελτιώσετε σημαντικά την εμπειρία χρήστη του ιστότοπού σας, να μειώσετε σημαντικά τον φόρτο του διακομιστή και να εξοικονομήσετε επισκεψιμότητα. Το κύριο πράγμα είναι να μην το παρακάνετε και να ρυθμίσετε τα πάντα σωστά, λαμβάνοντας υπόψη τα χαρακτηριστικά του πόρου σας.

    Η σωστά διαμορφωμένη προσωρινή αποθήκευση παρέχει τεράστια πλεονεκτήματα απόδοσης, εξοικονομεί εύρος ζώνης και μειώνει το κόστος διακομιστή, αλλά πολλοί ιστότοποι εφαρμόζουν κακώς την προσωρινή αποθήκευση, δημιουργώντας μια συνθήκη αγώνα που κάνει τους διασυνδεδεμένους πόρους να μην συγχρονίζονται.

    Συντριπτική πλειοψηφία βέλτιστες πρακτικέςΗ προσωρινή αποθήκευση αναφέρεται σε ένα από τα δύο μοτίβα:

    Pattern No.
    • Το περιεχόμενο της διεύθυνσης URL δεν αλλάζει, επομένως...
    • Το πρόγραμμα περιήγησης ή το CDN μπορεί εύκολα να αποθηκεύσει προσωρινά τον πόρο για ένα χρόνο
    • Το περιεχόμενο της προσωρινής αποθήκευσης που είναι μικρότερο από το καθορισμένο μέγιστο όριο ηλικίας μπορεί να χρησιμοποιηθεί χωρίς να συμβουλευτείτε τον διακομιστή

    Σελίδα: Γεια, χρειάζομαι "/script-v1.js" , "/styles-v1.css" και "/cats-v1.jpg" 10:24

    Μετρητά: Είμαι άδειος, τι λέτε εσείς, διακομιστή; 10:24

    Διακομιστής: Εντάξει, εδώ είναι. Με την ευκαιρία, μετρητά, θα πρέπει να χρησιμοποιηθούν για ένα χρόνο, όχι περισσότερο. 10:25

    Μετρητά: Ευχαριστώ! 10:25

    Σελίδα: Ωραία! 10:25

    Την επόμενη μέρα

    Σελίδα: Γεια, χρειάζομαι "/script-v2 .js" , "/styles-v2 .css" και "/cats-v1.jpg" 08:14

    Μετρητά: Υπάρχει μια φωτογραφία με γάτες, αλλά όχι τα υπόλοιπα. Υπηρέτης? 08:14

    Διακομιστής: Εύκολο - ορίστε το νέο CSS & JS. Για άλλη μια φορά, μετρητά: η διάρκεια ζωής τους δεν είναι μεγαλύτερη από ένα χρόνο. 08:15

    Μετρητά: Τέλεια! 08:15

    Σελίδα: Ευχαριστώ! 08:15

    Μετρητά: Χμμ, δεν έχω χρησιμοποιήσει τα "/script-v1.js" & "/styles-v1.css" εδώ και αρκετό καιρό. Ήρθε η ώρα να τα αφαιρέσετε. 12:32

    Χρησιμοποιώντας αυτό το μοτίβο, δεν αλλάζετε ποτέ το περιεχόμενο μιας συγκεκριμένης διεύθυνσης URL, αλλάζετε την ίδια τη διεύθυνση URL:

    Κάθε URL έχει κάτι που αλλάζει μαζί με το περιεχόμενο. Αυτός θα μπορούσε να είναι ένας αριθμός έκδοσης, μια τροποποιημένη ημερομηνία ή ένας κατακερματισμός περιεχομένου (αυτό που επέλεξα για το ιστολόγιό μου).

    Τα περισσότερα πλαίσια διακομιστή διαθέτουν εργαλεία που σας επιτρέπουν να κάνετε πράγματα όπως αυτό με ευκολία (στο Django χρησιμοποιώ το Manifest​Static​Files​Storage). Υπάρχουν επίσης πολύ μικρές βιβλιοθήκες στο Node.js που λύνουν τα ίδια προβλήματα, για παράδειγμα, gulp-rev.

    Ωστόσο, αυτό το μοτίβο δεν είναι κατάλληλο για πράγματα όπως άρθρα και αναρτήσεις ιστολογίου. Οι διευθύνσεις URL τους δεν μπορούν να τροποποιηθούν και το περιεχόμενό τους ενδέχεται να αλλάξει. Σοβαρά, έχω συχνά γραμματικά και λάθη στίξης και πρέπει να μπορώ να ενημερώνω γρήγορα το περιεχόμενο.

    Μοτίβο #2: μεταβλητό περιεχόμενο που επικυρώνεται πάντα στον διακομιστή Cache-Control: no-cache
    • Το περιεχόμενο της διεύθυνσης URL θα αλλάξει, πράγμα που σημαίνει...
    • Οποιαδήποτε έκδοση τοπικά αποθηκευμένη στην προσωρινή μνήμη δεν μπορεί να χρησιμοποιηθεί χωρίς τον καθορισμό του διακομιστή.

    Σελίδα: Γεια, χρειάζομαι τα περιεχόμενα των "/about/" και "/sw.js" 11:32

    Μετρητά: Δεν μπορώ να σε βοηθήσω. Υπηρέτης? 11:32

    Διακομιστής: Υπάρχουν μερικά. Μετρητά, κρατήστε τα μαζί σας, αλλά ρωτήστε με πριν τα χρησιμοποιήσετε. 11:33

    Μετρητά: Ακριβώς! 11:33

    Σελίδα: Ευχαριστώ! 11:33

    Την επόμενη μέρα

    Σελίδα: Γεια, χρειάζομαι ξανά τα περιεχόμενα των "/about/" και "/sw.js" 09:46

    Μετρητά: Ένα λεπτό. Διακομιστής, τα αντίγραφά μου είναι εντάξει; Το αντίγραφο του "/about/" είναι από τη Δευτέρα και το "/sw.js" είναι από χθες. 09:46

    Διακομιστής: "/sw.js" δεν έχει αλλάξει... 09:47

    Μετρητά: Cool. Σελίδα, κρατήστε το "/sw.js" . 09:47

    Διακομιστής: ...αλλά έχω "/about/" νέα έκδοση. Μετρητά, κρατήστε το, αλλά όπως και την προηγούμενη φορά, μην ξεχάσετε να με ρωτήσετε πρώτα. 09:47

    Μετρητά: Κατάλαβα! 09:47

    Σελίδα: Τέλεια! 09:47

    Σημείωση: η μη κρυφή μνήμη δεν σημαίνει "δεν υπάρχει προσωρινή αποθήκευση", σημαίνει "έλεγχος" (ή επανεπικύρωση) του αποθηκευμένου πόρου στον διακομιστή. Και το no-store λέει στο πρόγραμμα περιήγησης να μην αποθηκεύει καθόλου προσωρινά. Επίσης, η υποχρεωτική επανεπικύρωση δεν σημαίνει υποχρεωτική επανεπικύρωση, αλλά ότι ο αποθηκευμένος πόρος χρησιμοποιείται μόνο εάν είναι μικρότερος από την καθορισμένη μέγιστη ηλικία και μόνο διαφορετικά επικυρώνεται εκ νέου. Έτσι ξεκίνησαν όλα λέξεις-κλειδιάγια προσωρινή αποθήκευση.

    Σε αυτό το μοτίβο, μπορούμε να προσθέσουμε ένα ETag (αναγνωριστικό έκδοσης της επιλογής σας) ή μια κεφαλίδα Τελευταία Τροποποίηση στην απάντηση. Την επόμενη φορά που ο υπολογιστής-πελάτης ζητήσει περιεχόμενο, εξάγεται ένα If-None-Match ή If-Modified-Since, αντίστοιχα, επιτρέποντας στον διακομιστή να πει "Χρησιμοποιήστε αυτό που έχετε, η προσωρινή μνήμη σας είναι ενημερωμένη", δηλαδή να επιστρέψει το HTTP 304.

    Εάν η αποστολή ETag / Last-Modified δεν είναι δυνατή, ο διακομιστής στέλνει πάντα ολόκληρο το περιεχόμενο.

    Αυτό το μοτίβο απαιτεί πάντα κλήσεις δικτύου, επομένως δεν είναι τόσο καλό όσο το πρώτο μοτίβο, το οποίο μπορεί να γίνει χωρίς αιτήματα δικτύου.

    Δεν είναι ασυνήθιστο ότι δεν έχουμε την υποδομή για το πρώτο μοτίβο, αλλά μπορεί επίσης να προκύψουν προβλήματα με αιτήματα δικτύου στο μοτίβο 2. Ως αποτέλεσμα, χρησιμοποιείται μια ενδιάμεση επιλογή: σύντομη μέγιστη ηλικία και μεταβλητό περιεχόμενο. Αυτός είναι ένας κακός συμβιβασμός.

    Η χρήση του max-age με μεταβλητό περιεχόμενο είναι γενικά λάθος επιλογή

    Και, δυστυχώς, είναι κοινό· οι σελίδες Github είναι ένα παράδειγμα.

    Φαντάζομαι:

    • /άρθρο/
    • /styles.css
    • /script.js

    Με κεφαλίδα διακομιστή:

    Cache-Control: must-revalidate, max-age=600

    • αλλάζει περιεχόμενο URL
    • Εάν το πρόγραμμα περιήγησης έχει μια προσωρινά αποθηκευμένη έκδοση πιο πρόσφατη από 10 λεπτά, χρησιμοποιείται χωρίς να συμβουλευτείτε τον διακομιστή
    • Εάν δεν υπάρχει τέτοια κρυφή μνήμη, χρησιμοποιείται ένα αίτημα δικτύου, εάν είναι δυνατόν με If-Modified-Since ή If-None-Match

    Σελίδα: Γεια, χρειάζομαι "/article/", "/script.js" και "/styles.css" 10:21

    Μετρητά: Δεν έχω τίποτα, όπως εσύ, διακομιστής; 10:21

    Διακομιστής: Κανένα πρόβλημα, εδώ είναι. Αλλά θυμηθείτε, μετρητά: μπορούν να χρησιμοποιηθούν μέσα στα επόμενα 10 λεπτά. 10:22

    Μετρητά: Ναι! 10:22

    Σελίδα: Ευχαριστώ! 10:22

    Σελίδα: Γεια, χρειάζομαι ξανά τα "/article/" , "/script.js" και "/styles.css" 10:28

    Μετρητά: Ωχ, συγγνώμη, αλλά έχασα το "/styles.css", αλλά έχω όλα τα άλλα, ορίστε. Διακομιστής, μπορείτε να προσαρμόσετε το "/styles.css" για μένα; 10:28

    Διακομιστής: Εύκολα, έχει ήδη αλλάξει από την τελευταία φορά που τον πήρες. Μπορείτε να το χρησιμοποιήσετε με ασφάλεια για τα επόμενα 10 λεπτά. 10:29

    Μετρητά: Κανένα πρόβλημα. 10:29

    Σελίδα: Ευχαριστώ! Φαίνεται όμως ότι κάτι δεν πήγε καλά! Όλα είναι σπασμένα! Τι συμβαίνει? 10:29

    Αυτό το μοτίβο έχει δικαίωμα στη ζωή κατά τη διάρκεια των δοκιμών, αλλά σπάει τα πάντα σε ένα πραγματικό έργο και είναι πολύ δύσκολο να εντοπιστεί. Στο παραπάνω παράδειγμα, ο διακομιστής έχει ενημερώσει τα HTML, CSS και JS, αλλά η σελίδα αποδίδεται με τα παλιά αποθηκευμένα HTML και JS, συν το ενημερωμένο CSS από τον διακομιστή. Η αναντιστοιχία εκδόσεων καταστρέφει τα πάντα.

    Συχνά, όταν κάνουμε σημαντικές αλλαγές στο HTML, αλλάζουμε τόσο το CSS ώστε να αντικατοπτρίζει σωστά τη νέα δομή και το JavaScript για να συμβαδίζουμε με το περιεχόμενο και το στυλ. Όλοι αυτοί οι πόροι είναι ανεξάρτητοι, αλλά οι κεφαλίδες προσωρινής αποθήκευσης δεν μπορούν να το εκφράσουν αυτό. Ως αποτέλεσμα, οι χρήστες μπορεί να βρουν τον εαυτό τους τελευταία έκδοσηένας/δύο πόροι και η παλιά έκδοση των υπολοίπων.

    Η μέγιστη ηλικία ορίζεται σε σχέση με τον χρόνο απόκρισης, επομένως εάν όλοι οι πόροι μεταφερθούν ως μέρος μιας μεμονωμένης διεύθυνσης, θα λήξουν ταυτόχρονα, αλλά υπάρχει ακόμα μια μικρή πιθανότητα αποσυγχρονισμού. Εάν έχετε σελίδες που δεν περιλαμβάνουν JavaScript ή περιλαμβάνουν άλλα στυλ, οι ημερομηνίες λήξης της προσωρινής μνήμης τους θα είναι εκτός συγχρονισμού. Και χειρότερα, το πρόγραμμα περιήγησης τραβά συνεχώς περιεχόμενο από την κρυφή μνήμη, χωρίς να γνωρίζει ότι τα HTML, CSS και JS είναι αλληλεξαρτώμενα, οπότε μπορεί να βγάλει ευχάριστα ένα πράγμα από τη λίστα και να ξεχάσει όλα τα άλλα. Λαμβάνοντας υπόψη όλους αυτούς τους παράγοντες μαζί, θα πρέπει να καταλάβετε ότι η πιθανότητα αταίριαστων εκδόσεων είναι αρκετά υψηλή.

    Για τον χρήστη, το αποτέλεσμα μπορεί να είναι μια σπασμένη διάταξη σελίδας ή άλλα προβλήματα. Από μικρές δυσλειτουργίες έως εντελώς άχρηστο περιεχόμενο.

    Ευτυχώς, οι χρήστες έχουν έξοδο κινδύνου...

    Η ανανέωση της σελίδας μερικές φορές βοηθά

    Εάν η σελίδα φορτώνεται με ανανέωση, τα προγράμματα περιήγησης εκτελούν πάντα επανεπικύρωση από την πλευρά του διακομιστή, αγνοώντας τη μέγιστη ηλικία . Επομένως, εάν ο χρήστης έχει κάτι σπασμένο λόγω μέγιστης ηλικίας , μια απλή ανανέωση σελίδας μπορεί να διορθώσει τα πάντα. Αλλά, φυσικά, μετά την εύρεση των κουταλιών, το ίζημα θα παραμείνει και η στάση απέναντι στον ιστότοπό σας θα είναι κάπως διαφορετική.

    Ένας εργαζόμενος σέρβις μπορεί να παρατείνει τη διάρκεια ζωής αυτών των σφαλμάτων

    Για παράδειγμα, έχετε έναν υπάλληλο υπηρεσιών όπως αυτός:

    Έκδοση Const = "2"; self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`) .then(cache => cache.addAll([ "/styles.css", "/script .js" ]))); )); self.addEventListener("ενεργοποίηση", συμβάν => ( // ...διαγραφή παλαιών κρυφών μνήμων... )); self.addEventListener("fetch", event => ( event.respondWith(caches.match(event.request) .then(response => απάντηση || fetch(event. request)); ));

    Αυτός ο υπάλληλος υπηρεσιών:

    • κρυφή δέσμη ενεργειών και στυλ
    • χρησιμοποιεί προσωρινή μνήμη εάν υπάρχει αντιστοιχία, διαφορετικά έχει πρόσβαση στο δίκτυο

    Εάν αλλάξουμε το CSS/JS, αυξάνουμε επίσης τον αριθμό έκδοσης, το οποίο ενεργοποιεί μια ενημέρωση. Ωστόσο, δεδομένου ότι το addAll έχει πρόσβαση πρώτα στην προσωρινή μνήμη, μπορούμε να μπούμε σε κατάσταση αγώνα λόγω μέγιστης ηλικίας και αναντιστοιχίας εκδόσεων CSS & JS.

    Μόλις αποθηκευτούν στην κρυφή μνήμη, θα έχουμε ασύμβατο CSS & JS μέχρι την επόμενη ενημέρωση του εργαζομένου σέρβις - και αυτό είναι εκτός εάν βρεθούμε ξανά σε κατάσταση αγώνα κατά τη διάρκεια της ενημέρωσης.

    Μπορείτε να παραλείψετε την προσωρινή αποθήκευση στο Service Worker:

    Self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`) .then(cache => cache.addAll([ new Request("/styles.css", ( cache: "no-cache" )), new Request("/script.js", ( cache: "no-cache" )) ]))); ));

    Δυστυχώς, οι επιλογές για προσωρινή αποθήκευση δεν υποστηρίζονται στο Chrome/Opera και μόλις προστέθηκαν στη νυχτερινή έκδοση του Firefox, αλλά μπορείτε να το κάνετε μόνοι σας:

    Self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`) .then(cache => Promise.all([ "/styles.css", "/script .js" ].map(url => ( // cache-bust με χρήση συμβολοσειράς τυχαίου ερωτήματος που επιστρέφει fetch(`$(url)?$(Math.random())`).then(response => ( // fail σε 404, 500 κτλ. εάν (!response.ok) ρίξει Σφάλμα ("Όχι εντάξει"); επιστρέψτε cache.put(url, απάντηση); )) ))))); ));

    Σε αυτό το παράδειγμα, επαναφέρω τη μνήμη cache χρησιμοποιώντας έναν τυχαίο αριθμό, αλλά μπορείτε να προχωρήσετε περαιτέρω και να προσθέσετε έναν κατακερματισμό του περιεχομένου κατά τη δημιουργία (αυτό είναι παρόμοιο με αυτό που κάνει η sw-precache). Αυτό είναι ένα είδος υλοποίησης του πρώτου μοτίβου χρησιμοποιώντας JavaScript, αλλά λειτουργεί μόνο με τον εργαζόμενο της υπηρεσίας, όχι με προγράμματα περιήγησης και CDN.

    Οι εργαζόμενοι σε υπηρεσίες και η κρυφή μνήμη HTTP συνεργάζονται τέλεια, μην τους κάνετε να τσακώνονται!

    Όπως μπορείτε να δείτε, μπορείτε να επιλύσετε τα σφάλματα προσωρινής αποθήκευσης στον υπάλληλό σας, αλλά είναι καλύτερο να λύσετε τη ρίζα του προβλήματος. Σωστή ρύθμισηΗ προσωρινή αποθήκευση όχι μόνο διευκολύνει τη δουλειά του εργαζομένου σέρβις, αλλά βοηθά επίσης τα προγράμματα περιήγησης που δεν υποστηρίζουν τους εργαζόμενους σε υπηρεσίες (Safari, IE/Edge) και σας επιτρέπει επίσης να αξιοποιήσετε στο έπακρο το CDN σας.

    Οι σωστές κεφαλίδες προσωρινής αποθήκευσης μπορούν επίσης να κάνουν την ενημέρωση ενός υπαλλήλου υπηρεσιών πολύ πιο εύκολη.

    Έκδοση Const = "23"; self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`) .then(cache => cache.addAll([ "/", "/script-f93bca2c. js", "/styles-a837cb1e.css", "/cats-0e9a2ef4.jpg" ]))); ));

    Εδώ αποθήκευσα την αρχική σελίδα με το μοτίβο #2 (επανεπικύρωση από την πλευρά του διακομιστή) και όλους τους άλλους πόρους με μοτίβο #1 (αμετάβλητο περιεχόμενο). Κάθε ενημέρωση του υπαλλήλου σέρβις θα προκαλεί ένα αίτημα στη ριζική σελίδα και όλοι οι άλλοι πόροι θα φορτώνονται μόνο εάν έχει αλλάξει η διεύθυνση URL τους. Αυτό είναι καλό γιατί εξοικονομεί κίνηση και βελτιώνει την απόδοση, ανεξάρτητα από το αν κάνετε αναβάθμιση από προηγούμενο ή πολύ παλιά εκδοχή.

    Υπάρχει ένα σημαντικό πλεονέκτημα εδώ σε σχέση με την εγγενή υλοποίηση, όταν γίνεται λήψη ολόκληρου του δυαδικού αρχείου ακόμη και με μια μικρή αλλαγή ή προκαλεί μια περίπλοκη σύγκριση δυαδικά αρχεία. Με αυτόν τον τρόπο μπορούμε να ενημερώσουμε μια μεγάλη διαδικτυακή εφαρμογή με σχετικά μικρό φορτίο.

    Οι εργαζόμενοι σέρβις λειτουργούν καλύτερα ως βελτίωση παρά ως προσωρινό δεκανίκι, επομένως εργαστείτε με την κρυφή μνήμη αντί να την καταπολεμάτε.

    Όταν χρησιμοποιείται προσεκτικά, το περιεχόμενο μέγιστης ηλικίας και μεταβλητής μπορεί να είναι πολύ καλό

    Το max-age είναι πολύ συχνά η λάθος επιλογή για μεταβλητό περιεχόμενο, αλλά όχι πάντα. Για παράδειγμα, το αρχικό άρθρο έχει μέγιστη ηλικία τριών λεπτών. Η συνθήκη αγώνα δεν αποτελεί πρόβλημα, καθώς δεν υπάρχουν εξαρτήσεις στη σελίδα που χρησιμοποιούν το ίδιο μοτίβο προσωρινής αποθήκευσης (το CSS, το JS & οι εικόνες χρησιμοποιούν το μοτίβο #1 - αμετάβλητο περιεχόμενο), όλα τα άλλα δεν χρησιμοποιούν αυτό το μοτίβο.

    Αυτό το μοτίβο σημαίνει ότι μπορώ άνετα να γράψω ένα δημοφιλές άρθρο και το CDN μου (Cloudflare) μπορεί να αφαιρέσει το φορτίο από τον διακομιστή, αρκεί να είμαι πρόθυμος να περιμένω τρία λεπτά για να γίνει διαθέσιμο το ενημερωμένο άρθρο. προσβάσιμο στους χρήστες.

    Αυτό το μοτίβο πρέπει να χρησιμοποιείται χωρίς φανατισμό. Εάν πρόσθεσα μια νέα ενότητα σε ένα άρθρο και τη σύνδεσα από άλλο άρθρο, δημιούργησα μια εξάρτηση που πρέπει να επιλυθεί. Ο χρήστης μπορεί να κάνει κλικ στον σύνδεσμο και να λάβει ένα αντίγραφο του άρθρου χωρίς την επιθυμητή ενότητα. Αν θέλω να το αποφύγω, θα πρέπει να ανανεώσω το άρθρο, να διαγράψω την προσωρινά αποθηκευμένη έκδοση του άρθρου από το Cloudflare, να περιμένω τρία λεπτά και μόνο μετά να προσθέσω τον σύνδεσμο σε άλλο άρθρο. Ναι, αυτό το μοτίβο απαιτεί προσοχή.

    Όταν χρησιμοποιείται σωστά, η προσωρινή αποθήκευση παρέχει σημαντικές βελτιώσεις απόδοσης και εξοικονόμηση εύρους ζώνης. Προβάλετε αμετάβλητο περιεχόμενο εάν μπορείτε εύκολα να αλλάξετε τη διεύθυνση URL ή να χρησιμοποιήσετε επανεπικύρωση από την πλευρά του διακομιστή. Συνδυάστε περιεχόμενο μέγιστης ηλικίας και μεταβλητό περιεχόμενο, εάν είστε αρκετά γενναίοι και σίγουροι ότι το περιεχόμενό σας δεν έχει εξαρτήσεις που θα μπορούσαν να ξεφύγουν από το συγχρονισμό.

    Όταν κάνουμε αλλαγές σε ιστότοπους, συναντάμε συχνά το γεγονός ότι τα περιεχόμενα των σελίδων, των αρχείων css και των σεναρίων (.js) αποθηκεύονται προσωρινά από το πρόγραμμα περιήγησης και παραμένουν αμετάβλητα για μεγάλο χρονικό διάστημα. Αυτό οδηγεί στο γεγονός ότι για να αντικατοπτρίζονται οι αλλαγές που έγιναν σε όλα τα προγράμματα περιήγησης, είναι απαραίτητο να εξοικειωθούν οι πελάτες σε σύνθετους συνδυασμούς F5 ή Ctrl + F5. Και από καιρό σε καιρό φροντίστε να είναι πιεσμένα.

    Η διαδικασία είναι αρκετά κουραστική και άβολη. Μπορείτε, φυσικά, να βγείτε από την κατάσταση μετονομάζοντας τα αρχεία κάθε φορά, αλλά και πάλι είναι άβολο.

    Ωστόσο, υπάρχει ένας τρόπος που θα μας επιτρέψει να παραμείνουμε με τα ίδια ονόματα και να επαναφέρουμε την προσωρινή αποθήκευση των αρχείων .css ή .js τη στιγμή που το χρειαζόμαστε. Και ξεχάστε τα Ctrl + F5 για πάντα.

    Η ουσία είναι ότι θα επισυνάψουμε μια ψευδοπαράμετρο στα αρχεία μας .css ή .js στο τέλος, την οποία θα αλλάζουμε από καιρό σε καιρό, επαναφέροντας έτσι την προσωρινή μνήμη στο πρόγραμμα περιήγησης.

    Έτσι, η είσοδος σε πηγαίος κώδικαςτώρα θα μοιάζει με αυτό:

    Όπου το 186485 είναι ένας αυθαίρετος συνδυασμός που θα εξάγει το ίδιο αρχείο, αλλά το πρόγραμμα περιήγησης το ερμηνεύει ως νέο, χάρη στην ψευδοπαράμετρο ?186485

    Τώρα, για να μην αλλάζουμε όλες τις εμφανίσεις της παραμέτρου μας κάθε φορά, θα την ορίσουμε σε ένα αρχείο php, το οποίο θα συνδέσουμε σε όλα τα σημεία που χρειαζόμαστε: