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. Najlepšie postupy ukladania do vyrovnávacej pamäte Jednoduché ukladanie do vyrovnávacej pamäte ETag

Zahrnutím externých CSS a Javascriptu 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 ho majú vo vyrovnávacej pamäti stará verzia- kým cache nebude zastaraná, bude veľa sťažností na nefunkčnú integráciu serverovej a klientskej časti.

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 predvolene 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ých systémov) 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ívna možnosť- 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 uložiť do vyrovnávacej pamäte natrvalo 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) NEUKLADAJTE dokumenty do vyrovnávacej pamäte, ak je v adrese otáznik, pretože sa 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ží.

    Automatické pridávanie verzie k názvu súboru na stránke HTML

    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.

    Cache zohráva dôležitú úlohu pri prevádzke takmer každej webovej aplikácie na úrovni práce s databázami, web servermi a tiež na klientovi.

    V tomto článku sa pokúsime pochopiť ukladanie klientov do vyrovnávacej pamäte. Konkrétne sa pozrieme na to, aké hlavičky HTTP používajú prehliadače a webové servery a čo znamenajú.

    Najprv si však poďme zistiť, prečo je ukladanie do vyrovnávacej pamäte na strane klienta vôbec potrebné? .

    Webové stránky pozostávajú z mnohých rôzne prvky: obrázky, súbory css a js atď. Niektoré z týchto prvkov sa používajú na niekoľkých (mnohých) stránkach lokality. Ukladanie do vyrovnávacej pamäte na strane klienta sa týka schopnosti prehliadačov ukladať kópie súborov (odpovede servera), aby ich znova nesťahovali. To vám umožní výrazne urýchliť opätovné načítanie stránky, ušetriť na návštevnosti a tiež znížiť zaťaženie servera.

    Existuje niekoľko rôznych hlavičiek HTTP na riadenie procesov ukladania do vyrovnávacej pamäte na strane klienta. Povedzme si o každom z nich.

    Http hlavičky na ovládanie ukladania klienta do vyrovnávacej pamäte

    Najprv sa pozrime na to, ako server a prehliadač interagujú pri absencii akéhokoľvek ukladania do vyrovnávacej pamäte. Pre jasné pochopenie som sa snažil predstaviť a vizualizovať proces komunikácie medzi nimi formou textového chatu. Predstavte si na pár minút, že server a prehliadač sú ľudia, ktorí si navzájom dopisujú :)

    Bez vyrovnávacej pamäte (pri absencii ukladania hlavičiek http do vyrovnávacej pamäte)

    Ako vidíme, zakaždým, keď sa zobrazí obrázok cat.png, prehliadač ho znova stiahne zo servera. Myslím, že nie je potrebné vysvetľovať, že je to pomalé a neúčinné.

    Hlavička poslednej úpravy odpovede a hlavička požiadavky if-Modified-Since.

    Ide o to, že server pridá do súboru (odpoveď), ktorý dáva prehliadaču, hlavičku poslednej úpravy.

    Prehliadač teraz vie, že súbor bol vytvorený (alebo upravený) 1. decembra 2014. Keď bude prehliadač nabudúce potrebovať rovnaký súbor, odošle požiadavku s hlavičkou if-Modified-Since.

    Ak súbor nebol upravený, server odošle do prehliadača prázdnu odpoveď so stavom 304 (neupravené). V tomto prípade prehliadač vie, že súbor nebol aktualizovaný a môže zobraziť kópiu, ktorú naposledy uložil.

    Použitím Last-modified teda ušetríme na načítavaní veľký súbor, vystupuje s prázdnou rýchlou odpoveďou zo servera.

    Hlavička odpovede Etag a hlavička požiadavky If-None-Match.

    Princíp fungovania Etagu je veľmi podobný Last-modified, no na rozdiel od neho nie je viazaný na čas. Čas je relatívna vec.

    Myšlienka je taká, že keď je vytvorený a zakaždým, keď sa zmení, server označí súbor špeciálnou značkou s názvom ETag a tiež pridá hlavičku do súboru (odpoveď), ktorú odošle prehliadaču:

    ETAG: "686897696a7c876b7e"

    Teraz prehliadač vie, že súbor aktuálnej verzie má ETag rovný „686897696a7c876b7e“. Keď bude prehliadač nabudúce potrebovať rovnaký súbor, odošle požiadavku s hlavičkou If-None-Match: "686897696a7c876b7e" .

    If-None-Match: "686897696a7c876b7e"

    Server môže porovnať označenia a ak súbor nebol upravený, poslať do prehliadača prázdnu odpoveď so stavom 304 (neupravené). Rovnako ako pri Last-modified, prehliadač zistí, že súbor nebol aktualizovaný a bude môcť zobraziť kópiu z vyrovnávacej pamäte.

    Platnosť titulu vypršala

    Princíp fungovania tejto hlavičky sa líši od vyššie opísaných Etag a Last-modified. Pomocou Expired sa určí „dátum vypršania platnosti“ („obdobie relevantnosti“) súboru. Tie. Pri prvom načítaní server oznámi prehliadaču, že neplánuje zmeniť súbor do dátumu uvedeného v časti Expired:

    Nabudúce sa prehliadač s vedomím, že „dátum vypršania platnosti“ ešte nenaplnil, ani nepokúsi odoslať požiadavku na server a zobrazí súbor z vyrovnávacej pamäte.

    Tento typ vyrovnávacej pamäte je obzvlášť dôležitý pre ilustrácie článkov, ikony, ikony favicon, niektoré súbory css a js atď.

    Hlavička riadenia vyrovnávacej pamäte s príkazom max-age.

    Princíp fungovania Cache-control: max-age je veľmi podobný Expired. Tu je tiež určený „dátum vypršania platnosti“ súboru, ale je nastavený v sekundách a nie je viazaný na konkrétny čas, čo je vo väčšine prípadov oveľa pohodlnejšie.

    Pre informáciu:

    • 1 deň = 86 400 sekúnd
    • 1 týždeň = 604 800 sekúnd
    • 1 mesiac = 2629000 sekúnd
    • 1 rok = 31536000 sekúnd

    Napr.:

    Cache-Control: max-age=2629000;

    Hlavička Cache-control má okrem max-age aj iné direktívy. Poďme sa rýchlo pozrieť na tie najpopulárnejšie:

    verejnosti
    Faktom je, že požiadavky môže ukladať do vyrovnávacej pamäte nielen koncový klient používateľa (prehliadač), ale aj rôzne stredné proxy, siete CDN atď. Verejná direktíva teda umožňuje absolútne akémukoľvek proxy serveru vykonávať ukladanie do vyrovnávacej pamäte rovnako ako prehliadač.

    súkromné
    V smernici sa uvádza tento súbor(odpoveď servera) je špecifická pre koncového používateľa a nemala by byť ukladaná do vyrovnávacej pamäte rôznymi prostrednými proxy. Zároveň umožňuje cachovanie na koncového klienta (prehliadač používateľa). Toto je napríklad relevantné pre interné stránky profilu používateľa, požiadavky v rámci relácie atď.

    Umožňuje vám určiť, že klient by mal vždy zadať požiadavku na server. Niekedy sa používa s hlavičkou Etag opísanou vyššie.

    no-store
    Inštruuje klienta, že by si za žiadnych okolností nemal uchovávať kópiu žiadosti ani jej časti. Toto je najprísnejšia hlavička, ktorá prepíše všetky vyrovnávacie pamäte. Bol vynájdený špeciálne pre prácu s dôvernými informáciami.

    treba preveriť
    Táto direktíva dáva pokyn prehliadaču, aby povinne požiadal server o opätovné overenie obsahu (napríklad, ak používate eTag). Faktom je, že http v určitej konfigurácii umožňuje vyrovnávacej pamäti ukladať obsah, ktorý je už zastaraný. must-revalidate zaväzuje prehliadač, aby za každých okolností skontroloval aktuálnosť obsahu odoslaním požiadavky na server.

    proxy-revalidate
    Je to rovnaké ako pri nutnosti opätovného overenia, ale vzťahuje sa len na servery proxy na ukladanie do vyrovnávacej pamäte.

    s-maxage
    Prakticky sa nelíši od max-age , okrem toho, že túto direktívu berie do úvahy iba vyrovnávacia pamäť rôznych proxy serverov, ale nie samotný prehliadač používateľa. Písmeno „s -“ pochádza zo slova „shared“ (napr. CDN). Táto smernica je určená špecificky pre siete CDN a iné sprostredkovateľské vyrovnávacie pamäte. Jeho zadaním sa prepíšu hodnoty direktívy max-age a hlavičky Expired. Ak však nebudujete siete CDN, je nepravdepodobné, že by ste niekedy potrebovali s-maxage.

    Ako môžem vidieť, aké hlavičky sa používajú na stránke?

    Hlavičky http požiadaviek a hlavičky odpovedí si môžete pozrieť v ladiacom nástroji vášho obľúbeného prehliadača. Tu je príklad toho, ako to vyzerá v prehliadači Chrome:

    To isté možno vidieť v akomkoľvek prehliadači alebo http snifferi, ktorý rešpektuje seba samého.

    Nastavenie ukladania do vyrovnávacej pamäte v Apache a Nginx

    Nebudeme prerozprávať dokumentáciu na nastavenie populárnych serverov. Vždy sa na to dá pozerať a. Nižšie uvádzame niekoľko príkladov zo skutočného života, aby sme ukázali, ako vyzerajú konfiguračné súbory.

    Príklad Konfigurácie Apache na ovládanie Expires

    Nastavili sme rôzne „dátumy vypršania platnosti“. rôzne druhy súbory. Jeden rok pre obrázky, jeden mesiac pre skripty, štýly, pdf a ikony. Na všetko ostatné - 2 dni.

    ExpiresActive On ExpiresByType image/jpg "access plus 1 year" ExpiresByType image/jpeg "access plus 1 year" ExpiresByType image/gif "access plus 1 year" ExpiresByType image/png "access plus 1 year" Expires"ByTypeaccess plus text/cs mesiac" ExpiresByType application/pdf "prístup plus 1 mesiac" ExpiresByType text/x-javascript "prístup plus 1 mesiac" ExpiresByType image/x-ikona "prístup plus 1 rok" ExpiresDefault "prístup plus 2 dni"

    Príklad konfigurácie Nginx na ovládanie Expires

    Pre rôzne typy súborov sme nastavili rôzne „dátumy vypršania platnosti“. Jeden týždeň na obrázky, jeden deň na štýly a skripty.

    Server ( #... umiestnenie ~* \.(gif|ico|jpe?g|png)(\?+)?$ (platnosť vyprší 1 týždeň; ) umiestnenie ~* \.(css|js)$ (platnosť vyprší 1 d; ) #...)

    Príklad konfigurácie Apache pre Cache-control (max-age a public/private/no-cache) Header set Cache-Control "max-age=2592000, public" Header set Cache-Control "max-age=88000, private, must- revalidate" Sada hlavičiek Cache-Control "private, no-store, no-cache, must-revalidate, no-transform, max-age=0" Set hlavičiek Pragma "no-cache" Príklad konfigurácie Nginx pre server so statickými súbormi na kontrolu vyrovnávacej pamäte ( #... umiestnenie ~* \.(?:ico|css|js|gif|jpe?g|png)$ ( add_header Cache-Control "max-age=88000, public"; ) #... ) V záver

    „Ukladať do vyrovnávacej pamäte všetko, čo sa dá uložiť do vyrovnávacej pamäte“ je dobré motto pre vývojárov webu. Niekedy môžete stráviť len pár hodín konfiguráciou a zároveň výrazne zlepšiť používateľskú skúsenosť z vašej stránky, výrazne znížiť zaťaženie servera a ušetriť na návštevnosti. Hlavnou vecou nie je preháňať to a všetko správne nastaviť, berúc do úvahy vlastnosti vášho zdroja.

    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

    Strana: Ď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 potrebujem byť schopný rýchlo aktualizovať obsah.

    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

    Strana: Ď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 znova 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 určený maximálny vek a iba inak sa 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 (identifikátor 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é, ako príklad možno uviesť 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

    Strana: Ď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

    Strana: Ď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("aktivovať", udalosť => ( // …vymazať 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 stavu pretekov v dôsledku 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("Nie je v poriadku" 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 vyrovnávacia pamäť HTTP 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ž výrazne 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ú len vtedy, ak sa zmenila ich adresa URL. To je dobré, pretože to šetrí prevádzku a zlepšuje výkon, či už inovujete z predchádzajúceho alebo veľmi stará verzia.

    Tu je značná výhoda oproti natívnej implementácii, kedy sa stiahne celá binárka aj pri malej zmene alebo spôsobí zložité porovnanie binárne súbory. 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 pohodlne 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 k dispozícii. prístupné 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 sekcie, ktorú hľadá. 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žití 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 mohli byť nesynchronizované.

    Pri zmenách na webových stránkach sa často stretávame s tým, že obsah stránok, css súborov a skriptov (.js) prehliadač ukladá do vyrovnávacej pamäte a zostáva pomerne dlho nezmenený. To vedie k tomu, že aby sa vykonané zmeny prejavili vo všetkých prehliadačoch, je potrebné zvyknúť klientov na zložité kombinácie F5 alebo Ctrl + F5. A z času na čas sa uistite, že sú stlačené.

    Proces je dosť zdĺhavý a nepohodlný. Môžete sa, samozrejme, dostať zo situácie premenovaním súborov zakaždým, ale opäť je to nepohodlné.

    Existuje však spôsob, ktorý nám umožní zostať s rovnakými názvami a obnoviť vyrovnávaciu pamäť súborov .css alebo .js v momente, keď to potrebujeme. A zabudnite na Ctrl + F5 navždy.

    Základom je, že k našim .css alebo .js súborom na konci pripojíme pseudoparameter, ktorý z času na čas zmeníme, čím vynulujeme vyrovnávaciu pamäť v prehliadači.

    Teda vstup do zdrojový kód bude teraz vyzerať takto:

    Kde 186485 je ľubovoľná kombinácia, ktorá vygeneruje rovnaký súbor, ale prehliadač ho interpretuje ako nový vďaka pseudoparametru ?186485

    Teraz, aby sme zakaždým nemenili všetky výskyty nášho parametra, nastavíme ho do súboru php, ktorý pripojíme na všetky miesta, ktoré potrebujeme: