{"id":12362,"date":"2017-04-12T10:31:10","date_gmt":"2017-04-12T08:31:10","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=12362"},"modified":"2017-04-12T10:31:10","modified_gmt":"2017-04-12T08:31:10","slug":"dentro-i-meccanismi-di-cache-del-protocollo-http","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/dentro-i-meccanismi-di-cache-del-protocollo-http\/","title":{"rendered":"Dentro i meccanismi di cache del protocollo HTTP"},"content":{"rendered":"<p>Il protocollo HTTP \u00e8 il vettore privilegiato\u00a0per i servizi Internet\u00a0attivi nel mondo: ci riferiamo al World Wide Web, il cosiddetto WWW, \u00a0ma non solo. Lo scaricamento di dati e immagini riguarda buona parte delle risorse che tale protocollo impiega e il traffico generato pu\u00f2 essere ridotto sfruttando il meccanismo di <em>caching<\/em> gi\u00e0 appartenente al protocollo. <em>La cache permette al client (browser o nostre applicazioni) di conservare parte dei dati ottenuti da remoto e riutilizzarli per rispondere a\u00a0richieste future, senza necessit\u00e0 di scaricarli nuovamente dal server.<\/em> La finalit\u00e0 di un tale meccanismo \u00e8 evidente: risparmiamo banda, dati e tempo, guadagnando in efficienza.<\/p>\n<p>I dati salvati nella cache locale delle applicazioni devono essere conservati insieme ad una serie di informazioni accessorie come l&#8217;URL\u00a0dal quale sono stati ottenuti, data\/ora di scaricamento\u00a0ed opzionalmente\u00a0altro.\u00a0In s\u00e8 stesso, si tratta di un meccanismo semplice da comprendere e implementare, semmai il punto critico\u00a0\u00e8 capire fin quando tali dati saranno disponibili e come richiederli al server affinch\u00e8 vengano applicati i vantaggi del caching. Apprezzare il funzionamento della\u00a0cache \u00e8 fondamentale in quanto permette di sfruttarne i benefici e se ne pu\u00f2 trarre vantaggio sia lavorando lato server sia lato client come, ad esempio, nelle applicazioni mobile. In quest&#8217;ultimo caso si ricorder\u00e0 che diverse librerie gestiscono gi\u00e0 il meccanismo di cache (si pensi a <a href=\"https:\/\/developer.android.com\/training\/volley\/index.html\" target=\"_blank\">Volley<\/a> per Android) ma per farne buon uso \u00e8 fondamentale averlo compreso a fondo. In questo articolo, ne approfondiremo il funzionamento vedendo alcuni esempi in cui i dati scaricati si pongono in modo diverso rispetto al meccanismo di cache e analizzeremo bene lo scambio di informazioni mediante l&#8217;app\u00a0<a href=\"http:\/\/www.devapp.it\/wordpress\/postman-sviluppa-le-tue-api-piu-velocemente\/\" target=\"_blank\">Postman <\/a>di cui abbiamo parlato gi\u00e0 su questo sito.<\/p>\n<h2>Header HTTP e cache<\/h2>\n<p>Ricordiamo che una richiesta o risposta HTTP \u00e8\u00a0suddivisa in due emisferi diversi: ci sono da una parte le\u00a0<strong>header<\/strong>, le intestazioni, che accompagnano la comunicazione contenendo al proprio interno informazioni che la riguardano in quanto a\u00a0fattori come modalit\u00e0 e tempistiche; dall&#8217;altra parte ci sono i dati veri e propri, il <strong>message\u00a0body<\/strong>, quello che realmente percepir\u00e0 l&#8217;utente. In Postman vedremo chiaramente questa suddivisione e capiremo come viene applicato il meccanismo di cache all&#8217;interno di una comunicazione HTTP. <strong>Le intestazioni sono proprio gli elementi che\u00a0forniranno le principali indicazioni in materia di caching<\/strong>.<\/p>\n<h2>Cache-control: la header principale<\/h2>\n<p>La header fondamentale nell&#8217;utilizzo della cache HTTP \u00e8 <strong>cache-control<\/strong>. Questa pu\u00f2 innanzitutto decretare che i dati scaricati non debbano\u00a0essere conservati vedendo il suo valore\u00a0impostato a <strong>no-store<\/strong>. Tale situazione\u00a0dovrebbe verificarsi per dati che cambiano molto di frequente o che contengono informazioni troppo riservate per essere conservate nel browser o cache intermedie. Altro valore che limita l&#8217;azione di cache ma non la impedisce del tutto \u00e8 <strong>no-cache<\/strong> che impone di riutilizzare i dati salvati da una risposta precedente esclusivamente previo controllo di aggiornamenti presso il server.<\/p>\n<p>Qualora il server consideri <strong>auspicabile il caching dei dati<\/strong> offerti tramite un determinato URL, deve indicare in cache-control almeno due aspetti:<\/p>\n<ul>\n<li>qual \u00e8 la visibilit\u00e0 di tali dati: si indica <em>private<\/em> se solo il client finale pu\u00f2 conservarli o <em>public<\/em> se possono conservarli anche nodi di cache intermedi;<\/li>\n<li>qual \u00e8 il tempo di validit\u00e0 dei dati salvati. Si esprime in secondi grazie all&#8217;attributo <em>max-age<\/em> che indica, a partire dalla data di scaricamento,\u00a0per quanto tempo possono essere usati senza scaricarli nuovamente.<\/li>\n<\/ul>\n<p>E&#8217; importante specificare due aspetti. In primis, qualora cache-control non fosse presente nella risposta HTTP il caching non \u00e8 vietato anzi, al contrario, il client pu\u00f2 scegliere la politica che preferisce: come \u00e8 facile immaginare, questa non \u00e8 una situazione ideale in quanto il client per eseguire correttamente caching delle risposte ha bisogno di chiare indicazioni da parte del\u00a0server. Altro aspetto da considerare: si trova spesso nelle risposte HTTP l&#8217;intestazione <em>Expires<\/em> che indica fino a quando l&#8217;informazione scaricata pu\u00f2 essere conservata in cache. Il suo ruolo \u00e8 analogo a max-age ma si tenga presente\u00a0che nel protocollo HTTP 1.1 \u00e8 stato introdotto cache-control come indicazione complessiva per il caching pertanto non necessita di altro, incluso Expires.\u00a0Vediamo alcuni esempi di quanto detto sinora.<\/p>\n<h2>Esempio 1: caching del logo di Google<\/h2>\n<p>Le immagini vengono spesso immagazzinate in cache e ci\u00f2 avviene per almeno un paio di motivi: sono onerose come dimensioni rispetto al testo e cambiano raramente. Tra le immagini che vediamo nei siti Internet una categoria che cambia pochissime volte nel corso di molti anni sono i loghi. Pensiamo al logo di Google, uno dei pi\u00f9 famosi del web. Se apriamo l&#8217;homepage del motore di ricerca e cerchiamo l&#8217;URL dell&#8217;immagine otteniamo il seguente indirizzo:\u00a0<a href=\"https:\/\/www.google.it\/images\/branding\/googlelogo\/2x\/googlelogo_color_272x92dp.png\" target=\"_blank\">https:\/\/www.google.it\/images\/branding\/googlelogo\/2x\/googlelogo_color_272x92dp.png<\/a>.<\/p>\n<p>Apriamo Postman e facciamo una richiesta GET \u00a0all&#8217;URL del logo. Quello che segue \u00e8 la risposta che otteniamo:<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_01.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-12369\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_01.jpg\" alt=\"http-cache-postman_img_01\" width=\"649\" height=\"495\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_01.jpg 649w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_01-300x229.jpg 300w\" sizes=\"auto, (max-width: 649px) 100vw, 649px\" \/><\/a><\/p>\n<p>Nella sezione Headers della risposta vediamo che ci sono 11 intestazioni. Notiamo cache-control che permette di fare cache in maniera <em>private<\/em> e fissa come <em>max-age<\/em> un anno, qui espresso in secondi. Un programma client potr\u00e0 pertanto immagazzinare l&#8217;immagine scaricata e riutilizzarla per un anno al massimo.<\/p>\n<h2>Esempio 2: dati finanziari da non mettere in cache<\/h2>\n<p>Dal sito Yahoo!Finanza \u00e8 possibile scaricare in formato CSV dati finanziari aggiornati tramite appositi link. Ad esempio, per scaricare gli ultimi dati sull&#8217;indice di Borsa <a href=\"https:\/\/it.finance.yahoo.com\/q?s=FTSEMIB.MI\" target=\"_blank\">FTSE-MIB<\/a> si pu\u00f2 eseguire una richiesta GET all&#8217;indirizzo<a href=\"http:\/\/download.finance.yahoo.com\/d\/quotes.csv?s=FTSEMIB.MI&amp;f=sl1d1t1c1ohgv&amp;e=.csv\" target=\"_blank\">\u00a0http:\/\/download.finance.yahoo.com\/d\/quotes.csv?s=FTSEMIB.MI&amp;f=sl1d1t1c1ohgv&amp;e=.csv<\/a>\u00a0(lo abbiamo ricavato dal link con etichetta &#8220;Scarica dati&#8221; in basso a destra nella pagina web relativa all&#8217;indice).<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_04.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-12373\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_04.jpg\" alt=\"http-cache-postman_img_04\" width=\"676\" height=\"279\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_04.jpg 676w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_04-300x124.jpg 300w\" sizes=\"auto, (max-width: 676px) 100vw, 676px\" \/><\/a><\/p>\n<p>Tramite l&#8217;analisi offerta da Postman, vediamo che in cache-control ci sono chiare indicazioni di <strong>non effettuare cache<\/strong> di questi dati quindi ad ogni richiesta dell&#8217;utente essi andranno richiesti nuovamente al server.<\/p>\n<h2>Convalida della cache\u00a0con la\u00a0data di ultima modifica<\/h2>\n<p>Se il client conserva nella propria cache dei dati che andrebbero mostrati di nuovo all&#8217;utente ma che sono ormai scaduti, richiedendoli al server rischierebbe di scaricare ancora\u00a0gli stessi byte. Per un entry scaduta della cache si pu\u00f2 chiedere la convalida utilizzando l&#8217;ultima data di modifica. Torniamo all&#8217;esempio 1 e notiamo che l&#8217;ultima modifica al logo di Google (intestazione <strong>last-modified<\/strong>) \u00e8 stata apportata il 4 settembre 2015. Possiamo inviare pertanto una\u00a0richiesta contenente\u00a0l&#8217;intestazione\u00a0<em>If-modified-since<\/em> che indica al server a quale data risale il nostro salvataggio del logo in cache:<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_02.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-12370\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_02.jpg\" alt=\"http-cache-postman_img_02\" width=\"922\" height=\"419\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_02.jpg 922w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_02-300x136.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_02-768x349.jpg 768w\" sizes=\"auto, (max-width: 922px) 100vw, 922px\" \/><\/a><\/p>\n<p>Se la data del nostro salvataggio in cache \u00e8 pi\u00f9 recente dell&#8217;ultima data del contenuto su server, la risposta\u00a0conterr\u00e0 un codice HTTP 304 che significa &#8220;Not Modified&#8221; ma non l&#8217;immagine: ci\u00f2 vuol dire\u00a0che possiamo usare il logo che abbiamo in cache. Proviamo a fare un&#8217;altra richiesta in cui chiediamo se il logo non \u00e8 stato modificato dal 2014.<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_03.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-12371\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_03.jpg\" alt=\"http-cache-postman_img_03\" width=\"931\" height=\"484\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_03.jpg 931w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_03-300x156.jpg 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_03-768x399.jpg 768w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2016\/09\/http-cache-postman_img_03-500x261.jpg 500w\" sizes=\"auto, (max-width: 931px) 100vw, 931px\" \/><\/a><\/p>\n<p>Come possiamo vedere la risposta questa volta non \u00e8 un codice 304 bens\u00ec 200: in pratica il server supponendo che il client conservi in cache\u00a0un&#8217;immagine non pi\u00f9 valida ha direttamente offerto in download il logo come si vede dall&#8217;intestazione <em>content-length<\/em>.<\/p>\n<h2>Conclusioni<\/h2>\n<p>Un discorso simile pu\u00f2 sembrare troppo teorico ma in realt\u00e0 contiene un&#8217;estrema valenza pratica. <strong>Ogni tecnologia lato client dovrebbe\u00a0gestire la cache efficacemente per poter offrire migliori prestazioni<\/strong>. Per fortuna, questa funzionalit\u00e0 \u00e8 gi\u00e0 inclusa in molte librerie ma, d&#8217;altro canto, i programmatori conoscono poco il funzionamento della cache. Capire i concetti qui esposti \u00e8 fondamentale per poter usare correttamente il meccanismo ed offrire all&#8217;utente sempre prestazioni migliori.<\/p>\n<p>Alla prossima!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Il protocollo HTTP \u00e8 il vettore privilegiato\u00a0per i servizi Internet\u00a0attivi nel mondo: ci riferiamo al World Wide&#8230;<\/p>\n","protected":false},"author":561,"featured_media":12962,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[1729,1925,1926],"class_list":["post-12362","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-tutorial-pratici","tag-cache","tag-http-caching","tag-protocollo-http"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/12362","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/561"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=12362"}],"version-history":[{"count":15,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/12362\/revisions"}],"predecessor-version":[{"id":12963,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/12362\/revisions\/12963"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media\/12962"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=12362"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=12362"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=12362"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}