Základy ukladania klientov do vyrovnávacej pamäte jasnými slovami a príkladmi. Last-modified, Etag, Expires, Cache-control: max-age a ďalšie hlavičky

Mnoho ľudí si myslí, že v predvolenom nastavení sa súbory CSS pripojené cez odkaz alebo @import neukladajú do vyrovnávacej pamäte. Musím ťa sklamať. Presne zahrnuté css samostatný súbor cache, a veľmi dobre, povedal by som, že výborné. Tieto informácie boli spoľahlivo overené na 6 a vyšších a iných prehliadačoch. Stojí za zmienku, že veľa ľudí ukladá takéto súbory do vyrovnávacej pamäte divokou rýchlosťou, takže sa v tejto veci dostanú na prvé miesto. Mimochodom, v mnohých prípadoch je to práve tento mechanizmus, vďaka ktorému má Opera v porovnaní s inými prehliadačmi značnú rýchlosť. Okamžite však urobím výhradu, že práve toto „super“ ukladanie do vyrovnávacej pamäte v Opere si s ňou pri používaní technológie AJAX robí krutý vtip. Zatiaľ čo iní pomocou AJAX Kurčatá robia zmeny, Opera berie späť to staré. Ale toto je pieseň na samostatnú tému.

Ukladanie CSS do vyrovnávacej pamäte

ALE! Napriek tomu majú niektorí ľudia v tomto smere problémy. Je to zvyčajne spôsobené nesprávne nakonfigurovaným serverom Apache, ktorý vytvára nie úplne správne hlavičky. A pomocou hlavičky môžete ovládať ukladanie súborov do vyrovnávacej pamäte. V predvolenom nastavení je vyrovnávacia pamäť samozrejme vždy povolená. Sú však chvíle, keď nie je potrebné ukladať súbory do vyrovnávacej pamäte. Z tohto dôvodu dokonca aj profesionáli začínajú tancovať s tamburínami ohľadom HTTP hlavičiek. Ale ak si prečítate celý tento článok, potom ste ešte ďaleko od spravovania HTTP hlavičiek. Uisťujem vás, že s takýmto problémom sa v blízkej budúcnosti nestretnete. A napriek tomu, ak ste zvedaví až do jadra, stručne vám poviem, ako sa to deje.

  • pošle HTTP hlavičku na WEB server - hovoria, počúvaj, sladká paprika, daj mi CSS súbor, inak mám CSS, ale v poslednej dobe sú zmeny také a také.
  • A server mu hovorí, zlatko, od tej chvíle nenastali žiadne zmeny, pokojne vezmi a použi svoje staré CSS.
  • Ak sa CSS zmenil, prehliadač hlúpo aktualizuje CSS vo svojej vyrovnávacej pamäti.
  • No a teraz, ak nie som unavený, tak trochu vedeckého odpadu z nejakého experimentu.

    Hneď poviem, že spodný text bude pre nováčikov na WEB zle pochopený. Bude to užitočné najmä pre tých, ktorí stoja pred úlohou deaktivovať a povoliť vyrovnávaciu pamäť.

    Všetky experimenty boli vykonané na skutočnom, platenom. Dobrý hostiteľ, ktorý vám umožní zmeniť štruktúru HTTP hlavičiek bez toho, aby ste boli paranoidní, že budú hacknuté na základe HTTP hlavičky :)

    Režimy prehliadača

    Každý prehliadač má teda 2 režimy:

    1. Predvolený režim, návratová hlavička:

    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

    2. Režim s povolenou vyrovnávacou pamäťou, vrátená hlavička:

    Kontrola vyrovnávacej pamäte: súkromná, maximálny vek=10800, predbežná kontrola=10800

    Ďalej popisujem správanie prehliadačov FireFox 3.5 a vyššie

    V prvom režime pevne ukladá externé súbory JavaScript do vyrovnávacej pamäte a ani nekontroluje ich aktualizácie, pokiaľ nie je stránka nútená obnoviť. CSS je kontrolované požiadavkou hlavičky.

    If-Modified-Since: „aktuálny dátum“ GMT If-None-Match: „váš hash kód“

    To znamená, že CSS sa znova načíta, iba ak bol skutočne aktualizovaný.

    Po druhé, druhý režim úplne zastaví aktualizáciu stránky. To znamená, že aj keď sme zmenili obsah zobrazený na stránke v databáze, nezobrazí to, aj keď ju prinútime aktualizovať, pretože odošle požiadavku:

    GET / HTTP/1.1 Hostiteľ: xxx.com If-Modified-Since: aktuálny dátum GMT

    a dostane odpoveď:

    HTTP/1.1 304 Neupravené

    internet Explorer 8 (IE8)

    V prvom režime Internet Explorer odosiela požiadavky If-Modified-Since & If-None-Match pre JavaScript aj CSS, to znamená, že načíta JavaScript a CSS iba vtedy, ak boli skutočne aktualizované. To isté sa stane, ak vynútite obnovenie stránky.

    V druhom režime Internet Explorer tiež odosiela požiadavky If-Modified-Since & If-None-Match pre JavaScript aj css. No zároveň sa ani nepokúsi načítať/aktualizovať stránku samotnú, teda ani nepošle požiadavku, čiže vaše js/css sa aktualizuje, ale šablóna a obsah stránky nie. Pri aktualizácii obsahu nepomôže ani nútené obnovenie stránky.

    Opera 10 a staršia

    V prvom režime Opery v prvom režime závisí aktualizácia js & CSS od toho, na akú hodnotu je v nastaveniach nastavená možnosť Skontrolovať obrázky. Ak je možnosť nastavená na Vždy, Opera odošle požiadavky s If-Modified-Since & If-None-Match na kontrolu aktualizácií js a css. Ak je nastavená hodnota napr. 5 hodín, tak sa skontroluje podľa toho raz za 5 hodín, alebo násilným obnovením stránky.

    Po druhé, Opera nekontroluje aktualizáciu js & CSS (nevytvára požiadavky GET) a tiež nevytvára požiadavku GET na samotnú stránku, to znamená, že neuvidíme ani aktualizáciu js & css, ani aktualizáciu obsahu, ako v iných prípadoch a v iných prehliadačoch. Ale s vynútenou aktualizáciou je Opera lepšia. Na rozdiel od IE a FF, Opera explicitne požaduje obsah stránky bez If-Modified-Since a If-None-Match. Požiadavky na aktualizáciu js a CSS počas vynútenej aktualizácie už prichádzajú s funkciami If-Modified-Since a If-None-Match.

    závery
  • Ukladanie do vyrovnávacej pamäte, ak presne nerozumiete, ako to funguje rôzne prehliadače a ake ma nasledky - dost nebezpecna vec.
  • Ukladanie do vyrovnávacej pamäte je možné povoliť len vtedy, ak sa stránka aktualizuje zriedkavo (teda ak stránka nemá stránky, ktoré sa aktualizujú v reálnom čase) a aj v tomto prípade je potrebné nastaviť limit na dobu obmedzenia ukladania do vyrovnávacej pamäte (napr. , niekoľko hodín alebo deň)
  • FireFox sa podľa mňa správa o niečo inteligentnejšie ako IE, keďže aj pri zakázanom ukladaní do vyrovnávacej pamäte neustále nekontroluje aktualizácie JavaScriptu, čo sa zdá logické, pretože JavaScript sa aktualizuje veľmi zriedka.
  • Opera umožňuje flexibilne ovládať aktualizáciu obrázkov, JavaScript a CSS pomocou nastavenia Kontrola obrázkov, čo je plus. Opera sa tiež správa lepšie ako IE a FF so zapnutou vyrovnávacou pamäťou a vynútenou aktualizáciou, pretože, dovoľte mi pripomenúť, Opera v tomto prípade úplne aktualizuje obsah stránky a IE a FF vás zanechajú v blaženej nevedomosti.
  • Veľa šťastia pre vás a ziskové stránky.

    Správne nakonfigurované ukladanie do vyrovnávacej pamäte poskytuje obrovské výhody v oblasti výkonu, šetrí šírku pásma a znižuje náklady na server, ale mnohé lokality implementujú ukladanie do vyrovnávacej pamäte nedostatočne, čo spôsobuje konflikt, ktorý spôsobuje, že vzájomne prepojené zdroje sa nesynchronizujú.

    Drvivá väčšina osvedčené postupy ukladanie do vyrovnávacej pamäte sa vzťahuje na jeden z dvoch vzorov:

    Vzor č. 1: nemenný obsah a dlhá vyrovnávacia pamäť s maximálnym vekom Cache-Control: max-age=31536000
    • Obsah URL sa nemení, preto...
    • Prehliadač alebo CDN môže jednoducho ukladať zdroj do vyrovnávacej pamäte na rok
    • Obsah vo vyrovnávacej pamäti, ktorý je mladší ako určený maximálny vek, možno použiť bez konzultácie so serverom

    Stránka: Ahoj, potrebujem "/script-v1.js" , "/styles-v1.css" a "/cats-v1.jpg" 10:24

    Cash: Som prázdny, a čo ty, Server? 10:24

    Server: Dobre, tu sú. Mimochodom, Cash, mali by sa používať rok, nie viac. 10:25

    Cash: Ďakujem! 10:25

    Strana: Hurá! 10:25

    Nasledujúci deň

    Stránka: Ahoj, potrebujem "/script-v2 .js" , "/styles-v2 .css" a "/cats-v1.jpg" 08:14

    Hotovosť: Je tam obrázok s mačkami, ale nie zvyšok. server? 08:14

    Server: Jednoduché – tu je nový CSS a JS. Ešte raz, Cash: ich trvanlivosť nie je dlhšia ako rok. 08:15

    Hotovosť: Skvelé! 08:15

    Stránka: Ďakujem! 08:15

    Hotovosť: Hmm, už nejaký čas som nepoužil „/script-v1.js“ a „/styles-v1.css“. Je čas ich odstrániť. 12:32

    Pomocou tohto vzoru nikdy nezmeníte obsah konkrétnej adresy URL, zmeníte samotnú adresu URL:

    Každá adresa URL má niečo, čo sa mení spolu s obsahom. Môže to byť číslo verzie, upravený dátum alebo hash obsahu (čo som si vybral pre svoj blog).

    Väčšina rámcov na strane servera má nástroje, ktoré vám umožňujú robiť takéto veci jednoducho (v Django používam Manifest​Static​Files​Storage); V Node.js sú tiež veľmi malé knižnice, ktoré riešia rovnaké problémy, napríklad gulp-rev.

    Tento vzor však nie je vhodný pre veci ako články a blogové príspevky. Ich adresy URL nemožno upravovať a ich obsah sa môže zmeniť. Vážne, často mám gramatické chyby a interpunkčné chyby, a preto potrebujem príležitosť rýchla aktualizácia obsahu.

    Vzor č. 2: meniteľný obsah, ktorý je vždy overený na serveri Cache-Control: no-cache
    • Obsah adresy URL sa zmení, čo znamená...
    • Žiadna verzia uložená v lokálnej vyrovnávacej pamäti sa nedá použiť bez určenia servera.

    Stránka: Ahoj, potrebujem obsah "/about/" a "/sw.js" 11:32

    Cash: Nemôžem ti pomôcť. server? 11:32

    Server: Sú nejaké. Hotovosť, majte ich pri sebe, ale pred použitím sa ma opýtajte. 11:33

    Cash: Presne tak! 11:33

    Stránka: Ďakujem! 11:33

    Nasledujúci deň

    Stránka: Ahoj, potrebujem znova obsah "/about/" a "/sw.js" 09:46

    Hotovosť: Len minútu. Server, sú moje kópie v poriadku? Kópia „/about/“ je z pondelka a „/sw.js“ je zo včera. 09:46

    Server: "/sw.js" sa nezmenil... 09:47

    Hotovosť: V pohode. Stránka, ponechajte "/sw.js" . 09:47

    Server: …ale mám „/about/“ Nová verzia. Hotovosť, drž sa, ale ako minule, nezabudni sa ma najprv opýtať. 09:47

    Cash: Rozumiem! 09:47

    Strana: Skvelé! 09:47

    Poznámka: no-cache neznamená „neukladať do vyrovnávacej pamäte“, znamená to „skontrolovať“ (alebo opätovne overiť) uložený zdroj na serveri. A no-store povie prehliadaču, aby vôbec neukladal do vyrovnávacej pamäte. Tiež must-revalidate neznamená povinné opätovné overenie, ale to, že prostriedok uložený vo vyrovnávacej pamäti sa použije iba vtedy, ak je mladší ako zadaný maximálny vek a iba inak sa znova overí. Takto to celé začalo Kľúčové slová pre ukladanie do vyrovnávacej pamäte.

    V tomto vzore môžeme k odpovedi pridať ETag (ID verzie podľa vášho výberu) alebo hlavičku Last-Modified. Keď si klient nabudúce vyžiada obsah, vypíše sa If-None-Match alebo If-Modified-Since, čo umožňuje serveru povedať „Použite, čo máte, vaša vyrovnávacia pamäť je aktuálna“, t. j. vrátiť HTTP 304.

    Ak nie je možné odoslať ETag / Last-Modified, server vždy odošle celý obsah.

    Tento vzor vždy vyžaduje sieťové hovory, takže nie je taký dobrý ako prvý vzor, ​​ktorý sa zaobíde bez sieťových požiadaviek.

    Nie je nezvyčajné, že nemáme infraštruktúru pre prvý vzor, ​​ale môžu sa vyskytnúť aj problémy so sieťovými požiadavkami vo vzore 2. V dôsledku toho sa používa prechodná možnosť: krátky maximálny vek a premenlivý obsah. Toto je zlý kompromis.

    Použitie maximálneho veku s meniteľným obsahom je vo všeobecnosti nesprávna voľba

    A, bohužiaľ, je to bežné; príkladom sú stránky Github.

    Predstavte si:

    • /článok/
    • /styles.css
    • /script.js

    S hlavičkou servera:

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

    • Obsah adresy URL sa zmení
    • Ak má prehliadač verziu uloženú vo vyrovnávacej pamäti novšiu ako 10 minút, použije sa bez konzultácie so serverom
    • Ak takáto vyrovnávacia pamäť neexistuje, použije sa sieťová požiadavka, ak je to možné, s If-Modified-Since alebo If-None-Match

    Stránka: Ahoj, potrebujem "/článok/", "/script.js" a "/styles.css" 10:21

    Cash: Nemám nič, ako ty, server? 10:21

    Server: Žiadny problém, tu sú. Pamätajte však, že hotovosť: môžu byť použité v priebehu nasledujúcich 10 minút. 10:22

    Hotovosť: Áno! 10:22

    Stránka: Ďakujem! 10:22

    Stránka: Ahoj, potrebujem znova "/article/", "/script.js" a "/styles.css" 10:28

    Cash: Ups, prepáčte, ale stratil som „/styles.css“, ale všetko ostatné mám, tu to máte. Server, môžete mi prispôsobiť "/styles.css"? 10:28

    Server: Pokojne, už sa zmenil, odkedy ste ho naposledy vzali. Ďalších 10 minút ho môžete pokojne používať. 10:29

    Hotovosť: Žiadny problém. 10:29

    Stránka: Ďakujem! Ale zdá sa, že sa niečo pokazilo! Všetko je rozbité! Čo sa deje? 10:29

    Tento vzor má právo na život počas testovania, ale v skutočnom projekte rozbije všetko a je veľmi ťažké ho sledovať. Vo vyššie uvedenom príklade server aktualizoval HTML, CSS a JS, ale stránka sa vykresľuje pomocou starého kódu HTML a JS uloženého vo vyrovnávacej pamäti plus aktualizovaného CSS zo servera. Nesúlad verzií ničí všetko.

    Keď robíme významné zmeny v HTML, často meníme CSS tak, aby správne odrážali novú štruktúru, aj JavaScript, aby sme držali krok s obsahom a štýlom. Všetky tieto zdroje sú nezávislé, ale hlavičky ukladania do vyrovnávacej pamäte to nedokážu vyjadriť. V dôsledku toho môžu používatelia nájsť sami seba Najnovšia verzia jeden/dva zdroje a stará verzia zvyšku.

    max-age je nastavený relatívne k času odozvy, takže ak sa všetky zdroje prenesú ako súčasť jednej adresy, ich platnosť vyprší v rovnakom čase, ale stále existuje malá šanca na desynchronizáciu. Ak máte stránky, ktoré neobsahujú JavaScript alebo obsahujú iné štýly, dátumy vypršania platnosti ich vyrovnávacej pamäte nebudú synchronizované. A čo je horšie, prehliadač neustále vyťahuje obsah z vyrovnávacej pamäte, pričom nevie, že HTML, CSS a JS sú vzájomne závislé, takže môže veselo vytiahnuť jednu vec zo zoznamu a zabudnúť na všetko ostatné. Ak vezmeme do úvahy všetky tieto faktory spolu, mali by ste pochopiť, že pravdepodobnosť nezhodných verzií je dosť vysoká.

    Pre používateľa môže byť výsledkom nefunkčné rozloženie stránky alebo iné problémy. Od malých prešľapov až po úplne nepoužiteľný obsah.

    Našťastie, používatelia majú núdzový východ...

    Obnovenie stránky niekedy pomôže

    Ak sa stránka načíta obnovou, prehliadače vždy vykonajú opätovné overenie na strane servera, pričom budú ignorovať maximálny vek . Preto, ak má používateľ niečo pokazené kvôli max-age , jednoduché obnovenie stránky môže všetko opraviť. Ale, samozrejme, po nájdení lyžičiek zostane sediment a postoj k vašej stránke bude trochu iný.

    Servisný pracovník môže predĺžiť životnosť týchto chýb

    Máte napríklad servisného pracovníka, ako je tento:

    Konštantná verzia = "2"; self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`) .then(cache => cache.addAll([ "/styles.css", "/script .js" ]))); )); self.addEventListener("activate", event => ( // ...zmazať staré cache... )); self.addEventListener("fetch", event => ( event.respondWith(caches.match(event.request) .then(response => response || fetch(event.request))); ));

    Tento servisný pracovník:

    • cache skript a štýly
    • používa vyrovnávaciu pamäť, ak existuje zhoda, inak pristupuje k sieti

    Ak zmeníme CSS/JS, zvýšime aj číslo verzie, čo spustí aktualizáciu. Keďže však addAll pristupuje ku vyrovnávacej pamäti ako prvý, môžeme sa dostať do pretekárskeho stavu z dôvodu maximálneho veku a nesúladu verzií CSS a JS.

    Keď sa uložia do vyrovnávacej pamäte, budeme mať nekompatibilné CSS a JS až do ďalšej aktualizácie servisného pracovníka – a to pokiaľ sa počas aktualizácie opäť nedostaneme do konfliktného stavu.

    Ukladanie do vyrovnávacej pamäte môžete preskočiť v servisnom pracovníkovi:

    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" )) ]))); ));

    Bohužiaľ, možnosti ukladania do vyrovnávacej pamäte nie sú podporované v prehliadači Chrome/Opera a boli práve pridané do nočnej zostavy Firefoxu, ale môžete to urobiť sami:

    Self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`) .then(cache => Promise.all([ "/styles.css", "/script .js" ].map(url => ( // zrušenie vyrovnávacej pamäte pomocou náhodného reťazca dotazu return fetch(`$(url)?$(Math.random())`).then(response => ( // neúspešné na 404, 500 atď. if (!response.ok) throw Error("Not ok"); return cache.put(url, response); )) ))))); ));

    V tomto príklade resetujem vyrovnávaciu pamäť pomocou náhodného čísla, ale môžete ísť ďalej a pri vytváraní pridať hash obsahu (toto je podobné tomu, čo robí sw-precache). Toto je druh implementácie prvého vzoru pomocou JavaScriptu, ale funguje iba so servisným pracovníkom, nie s prehliadačmi a CDN.

    Servisní pracovníci a HTTP cache skvele spolupracujú, nenúťte ich bojovať!

    Ako vidíte, chyby ukladania do vyrovnávacej pamäte môžete obísť u svojho servisného pracovníka, ale je lepšie vyriešiť koreň problému. Správne nastavenie ukladanie do vyrovnávacej pamäte nielenže uľahčuje prácu servisnému pracovníkovi, ale pomáha aj prehliadačom, ktoré nepodporujú servisných pracovníkov (Safari, IE/Edge), a tiež vám umožňuje vyťažiť maximum z vášho CDN.

    Správne hlavičky ukladania do vyrovnávacej pamäte môžu tiež značne uľahčiť aktualizáciu servisného pracovníka.

    Konštantná verzia = "23"; self.addEventListener("install", event => ( event.waitUntil(caches.open(`static-$(version)`) .then(cache => cache.addAll([ "/", "/script-f93bca2c. js", "/styles-a837cb1e.css", "/cats-0e9a2ef4.jpg" ]))); ));

    Tu som uložil koreňovú stránku so vzorom #2 (revalidácia na strane servera) a všetky ostatné zdroje so vzorom #1 (nezmeniteľný obsah). Každá aktualizácia servisného pracovníka spôsobí požiadavku na koreňovú stránku a všetky ostatné zdroje sa načítajú iba vtedy, ak sa zmenila ich adresa URL. To je dobré, pretože to šetrí prevádzku a zlepšuje výkon bez ohľadu na to, či inovujete z predchádzajúcej alebo veľmi stará verzia.

    Tu je značná výhoda oproti natívnej implementácii, kde sa stiahne celá binárka aj pri malej zmene alebo spôsobí zložité binárne porovnanie. Dokážeme tak aktualizovať veľkú webovú aplikáciu s relatívne malým zaťažením.

    Servisní pracovníci fungujú lepšie ako vylepšenie, nie ako dočasná barlička, takže namiesto boja s vyrovnávacou pamäťou pracujte.

    Pri opatrnom používaní môže byť maximálny vek a variabilný obsah veľmi dobrý

    max-age je veľmi často nesprávna voľba pre meniteľný obsah, ale nie vždy. Napríklad pôvodný článok má maximálny vek tri minúty. Rate condition nie je problém, pretože neexistujú žiadne závislosti na stránke používajúcej rovnaký vzor ukladania do vyrovnávacej pamäte (CSS, JS a obrázky používajú vzor #1 - nemenný obsah), všetko ostatné tento vzor nepoužíva.

    Tento vzor znamená, že môžem ľahko napísať populárny článok a môj CDN (Cloudflare) môže znížiť zaťaženie servera, pokiaľ som ochotný počkať tri minúty, kým bude aktualizovaný článok dostupný používateľom.

    Tento vzor by sa mal používať bez fanatizmu. Ak som do článku pridal novú sekciu a prepojil som na ňu z iného článku, vytvoril som závislosť, ktorú treba vyriešiť. Používateľ môže kliknúť na odkaz a získať kópiu článku bez požadovanej sekcie. Ak sa tomu chcem vyhnúť, mal by som obnoviť článok, vymazať uloženú verziu článku z Cloudflare, počkať tri minúty a až potom pridať odkaz na ďalší článok. Áno, tento vzor si vyžaduje opatrnosť.

    Pri správnom používaní poskytuje ukladanie do vyrovnávacej pamäte výrazné zlepšenie výkonu a úsporu šírky pásma. Poskytujte nemenný obsah, ak môžete jednoducho zmeniť adresu URL, alebo použite opätovné overenie na strane servera. Zmiešajte maximálny vek a meniteľný obsah, ak ste dostatočne odvážni a ste si istí, že váš obsah nemá závislosti, ktoré by sa mohli nesynchronizovať.

    Pripája sa externý CSS a Javascript, chceme znížiť zbytočné HTTP požiadavky na minimum.

    Na tento účel sa súbory .js a .css poskytujú s hlavičkami, ktoré zaisťujú spoľahlivé ukladanie do vyrovnávacej pamäte.

    Čo však urobíte, keď sa jeden z týchto súborov počas vývoja zmení? Všetci používatelia majú starú verziu vo svojej vyrovnávacej pamäti - kým vyrovnávacia pamäť nebude zastaraná, bude sa veľa sťažovať na nefunkčnú integráciu serverových a klientskych častí.

    Správne ukladanie do vyrovnávacej pamäte a vytváranie verzií tento problém úplne odstraňuje a poskytuje spoľahlivú a transparentnú synchronizáciu verzií štýlu/skriptov.

    Jednoduché ukladanie ETag do vyrovnávacej pamäte

    Najjednoduchším spôsobom ukladania statických zdrojov do vyrovnávacej pamäte je použitie ETag.

    Stačí povoliť príslušné nastavenie servera (pre Apache je štandardne povolené) - a pre každý súbor v hlavičkách bude uvedený ETag - hash, ktorý závisí od času aktualizácie, veľkosti súboru a (na základe inode súborové systémy) inode.

    Prehliadač uloží takýto súbor do vyrovnávacej pamäte a pri ďalších požiadavkách určí hlavičku If-None-Match s ETag dokumentu uloženého vo vyrovnávacej pamäti. Po prijatí takejto hlavičky môže server odpovedať kódom 304 - a potom sa dokument vyberie z vyrovnávacej pamäte.

    Vyzerá to takto:

    Prvá požiadavka na server (vyčistenie vyrovnávacej pamäte) GET /misc/pack.js HTTP/1.1 Hostiteľ: webová stránka

    Vo všeobecnosti prehliadač zvyčajne pridáva veľa hlavičiek ako User-Agent, Accept atď. Sú strihané kvôli stručnosti.

    Odozva servera Server odpovie dokumentom s kódom 200 a ETag: HTTP/1.x 200 OK Kódovanie obsahu: gzip Typ obsahu: text/javascript; charset=utf-8 Etag: "3272221997" Accept-Ranges: bytes Content-Length: 23321 Date: Pi, 02 May 2008 17:22:46 GMT Server: lighttpd Ďalšia požiadavka prehliadača Pri ďalšej požiadavke prehliadač pridá If-None -Match: (uložené ETag): GET /misc/pack.js HTTP/1.1 Hostiteľ: site If-None-Match: "453700005" Odpoveď servera Server vyzerá - áno, dokument sa nezmenil. To znamená, že môžete vydať kód 304 a dokument neodoslať znova. HTTP/1.x 304 Neupravené Kódovanie obsahu: gzip Etag: "453700005" Typ obsahu: text/javascript; charset=utf-8 Accept-Ranges: bytes Dátum: Ut, 15 Apr 2008 10:17:11 GMT

    Alternatívou je, že ak sa dokument zmenil, server jednoducho odošle 200 s novým ETag.

    Kombinácia Last-Modified + If-Modified-Since funguje podobným spôsobom:

  • server odošle dátum poslednej úpravy v hlavičke Last-Modified (namiesto ETag)
  • prehliadač uloží dokument do vyrovnávacej pamäte a pri ďalšej požiadavke na rovnaký dokument odošle dátum verzie uloženej vo vyrovnávacej pamäti v hlavičke If-Modified-Since (namiesto If-None-Match)
  • server skontroluje dátumy a ak sa dokument nezmenil, odošle iba kód 304 bez obsahu.
  • Tieto metódy fungujú spoľahlivo a dobre, ale prehliadač musí aj tak urobiť požiadavku na každý skript alebo štýl.

    Inteligentné ukladanie do vyrovnávacej pamäte. Verziovanie

    Všeobecný prístup k verziám - v skratke:

  • Verzia (alebo dátum úpravy) sa pridá do všetkých skriptov. Napríklad http://site/my.js sa zmení na http://site/my.v1.2.js
  • Všetky skripty sú pevne uložené vo vyrovnávacej pamäti prehliadača
  • Pri aktualizácii skriptu sa verzia zmení na novú: http://site/my.v2.0.js
  • Adresa sa zmenila, takže prehliadač si znova vyžiada súbor a uloží ho do vyrovnávacej pamäte
  • Stará verzia 1.2 bude postupne vypadávať z cache
  • Ťažké ukladanie do vyrovnávacej pamäte

    Ťažké ukladanie do vyrovnávacej pamäte- druh kladiva, ktoré úplne pribije požiadavky servera na dokumenty uložené vo vyrovnávacej pamäti.

    Ak to chcete urobiť, stačí pridať hlavičky Expires a Cache-Control: max-age.

    Ak chcete napríklad uložiť do vyrovnávacej pamäte na 365 dní v PHP:

    Hlavička("Platnosť vyprší: ".gmdate("D, d M Y H:i:s", čas()+86400*365)." GMT"); header("Cache-Control: max-age="+86400*365);

    Alebo môžete obsah natrvalo uložiť do vyrovnávacej pamäte pomocou mod_header v Apache:

    Po prijatí takýchto hlavičiek prehliadač pevne ukladá dokument do vyrovnávacej pamäte na dlhú dobu. Všetok ďalší prístup k dokumentu bude poskytovaný priamo z vyrovnávacej pamäte prehliadača bez kontaktovania servera.

    Väčšina prehliadačov (Opera, Internet Explorer 6+, Safari) NEUKLADÁVA dokumenty do vyrovnávacej pamäte, ak je v adrese otáznik, pretože ich považujú za dynamické.

    Preto k názvu súboru pridávame verziu. Samozrejme, pri takýchto adresách musíte použiť riešenie ako mod_rewrite, na to sa pozrieme neskôr v článku.

    P.S. Ale Firefox ukladá adresy do vyrovnávacej pamäte s otáznikmi...

    Automatické rozlíšenie názvu

    Pozrime sa na to, ako automaticky a transparentne meniť verzie bez premenovania samotných súborov.

    Názov s verziou -> Súbor

    Najjednoduchšie je zmeniť názov s verziou na pôvodný názov súboru.

    Na úrovni Apache sa to dá urobiť pomocou mod_rewrite:

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

    Toto pravidlo spracuje všetky súbory css/js/gif/png/jpg a odstráni verziu z názvu.

    Napríklad:

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

    Ale okrem vystrihnutia verzie musíte do súborov pridať aj hlavičky s pevnou vyrovnávacou pamäťou. Na to sa používajú direktívy mod_header:

    Pridať hlavičku "Platnosť vyprší" "Po, 28. júl 2014 23:30:00 GMT" Pridať hlavičku "Cache-Control" "max-age=315360000"

    A spolu to implementuje nasledujúcu konfiguráciu Apache:

    RewriteEngine on # odstráni verziu a zároveň nastaví premennú, že súbor má verziu RewriteRule ^/(.*\.)v+\.(css|js|gif|png|jpg)$ /$1$2 # hard cache súbory s verziou Pridať hlavičku "Platnosť vyprší" "Po, 28. júl 2014 23:30:00 GMT" env=VERSIONED_FILE Pridať hlavičku "Cache-Control" "max-age=315360000" env=VERSIONED_FILE

    Vzhľadom na spôsob, akým modul mod_rewrite funguje, musí byť RewriteRule umiestnené v hlavnom konfiguračný súbor httpd.conf alebo zahrnuté súbory, ale nikdy nie v .htaccess , inak sa najskôr spustia príkazy Header pred nastavením premennej VERSIONED_FILE.

    Direktívy hlavičky môžu byť kdekoľvek, dokonca aj v .htaccess – na tom nezáleží.

    Automaticky pridávať verziu k súboru na HTML stránke

    Spôsob vloženia verzie do názvu skriptu závisí od vášho systému šablón a vo všeobecnosti od spôsobu pridávania skriptov (štýlov atď.).

    Napríklad pri použití dátumu modifikácie ako verzie a nástroja Smarty šablóny možno odkazy nastaviť takto:

    Funkcia verzie pridá verziu:

    Function smarty_version($args)( $stat = stat($GLOBALS["config"]["site_root"].$args["src"]); $version = $stat["mtime"]; echo preg_replace("! \.(+?)$!", ".v$version.\$1", $args["src"]); )

    Výsledok na stránke:

    Optimalizácia

    Aby ste sa vyhli zbytočným volaniam štatistík, môžete pole so zoznamom aktuálnych verzií uložiť do samostatnej premennej

    $versions["css"] = array("group.css" => "1.1", "other.css" => "3.0", )

    V tomto prípade sa aktuálna verzia z poľa jednoducho nahradí do kódu HTML.

    Môžete skrížiť oba prístupy a počas vývoja vytvoriť verziu podľa dátumu úpravy - pre relevantnosť a vo výrobe - verziu z poľa pre výkon.

    Použiteľnosť

    Táto metóda ukladania do vyrovnávacej pamäte funguje všade, vrátane Javascriptu, CSS, obrázkov, Flash filmov atď.

    Je to užitočné vždy, keď sa dokument zmení, ale prehliadač by mal mať vždy aktuálnu, aktuálnu verziu.