jblog: news e appunti per webmaster
 

Green ArchiveIniziamo una lunga serie di articoli sull’ottimizzazione dei siti web in cui verranno trattate le tecniche e i suggerimenti per rendere efficiente il proprio sito web.

In questo articolo parlo della cache dei browser, come e perché gestirla. Vedrai cos’è una richiesta http, un’intestazione http e le tre tecniche principali per istruire il browser su come dovrà comportarsi con gli elementi di una pagina, cioé, quando leggerli dal server d’origine e quando caricarli dalla cache.

Cos’è una richiesta http?

Quando il browser visita un sito apre una connessione con l’host (il server che ospita il sito), composta da una richiesta e da una risposta. Supponiamo di voler visitare la pagina http://jblog.it/informazioni.html.

La richiesta http che invia il browser

GET /informazioni HTTP/1.1
Host: jblog.it
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; it; rv:1.9.0.8) Gecko/2009032609 Firefox/3.0.8
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: it
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

La risposta http

HTTP/1.1 200 OK
Date: Fri, 24 Apr 2009 10:26:08 GMT
Server: Apache
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=UTF-8

Le informazioni inviate e restituite potrebbero essere molte di più, ognuna ha un suo preciso significato, e possono essere controllate e gestite via codice (lato client e lato server). Sul sito del w3c puoi trovare l’elenco completo dei campi di intestazione delle connessioni http: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html.

La prima riga della richiesta: GET /informazioni HTTP/1.1

In questa riga si trovano sostanzialmente tre informazioni: il tipo della richiesta (GET, POST, HEAD, PUT, DELETE, OPTIONS, TRACE), l’indirizzo della risorsa (/informazioni) e il protocollo con cui si effettua la richiesta (HTTP/1.1).

La prima riga della risposta: HTTP/1.1 200 OK

Il codice 200 indica il successo della risposta http. Esistono vari codici numerici per indicare l’esito della risposta http. Ad esempio, il classico codice 404 indica che non è stata trovata la risorsa specificata nella richiesta http. Se ti interessa puoi trovare una lista completa su wikipedia: http://it.wikipedia.org/wiki/Elenco_dei_codici_di_stato_HTTP.

Perché bisogna ridurre le richieste http?

Il numero di richieste http dipende dal numero di elementi da caricare. Ad esempio, se in una pagina ci sono 2 immagini e 1 foglio di stile il browser effettuerà 4 richieste http (una è per il codice html della pagina).

Come avrai ben capito, la regola è “ridurre gli elementi della pagina”, o meglio “ottimizzare gli elementi di una pagina senza eliminarne nessuno”. Con “ottimizzare” non intendo “ridurre la loro dimensione”. Infatti riducendo la dimensione degli elementi avresti un miglior tempo di caricamento mantenendo lo stesso numero di richieste http.

Ottimizzare o ridurre?

Senza dubbio è importantissimo ottimizzare la qualità e le dimensioni dei componenti di una pagina, ma una singola richiesta http è molto più gravosa di qualche kbyte in più. Ecco perché ridurre le richieste http è fondamentale.

I campi di intestazione del protocollo HTTP per gestire la cache

Gift TagIl protocollo HTTP 1.1 ha alcuni campi di intestazione (o header fields) che consentono di fornire alcune informazioni riguardo un file (data, ultima modifica, periodo, ecc.) e controllare la cache.

Cache-Control

Specifica le direttive che devono rispettare tutti i metodi di caching dei componenti restituiti. Le direttive di cache-control:

  1. sovrascrivono gli algoritmi di caching di default
  2. non possono essere specificate per una singola cache (se si utilizza un proxy o un gateway)
  3. sono unidirezionali, cioè non implicano che la risposta abbia le stesse direttive

Alcune direttive possono essere utilizzate solo in fase di richiesta o solo in fase di risposta.

  • direttive di richiesta: no-cache, no-store, max-age, max-stale, min-fresh, no-transform, only-if-cached, cache-extension.
  • direttive di risposta: public, private, no-cache, no-store, no-transform, must-revalidate, proxy-revalidate, max-age, s-maxage, cache-extension.

public. La risposta può essere memorizzata in qualsiasi cache. Utile se si utilizza una cache condivisa.

private. La risposta non deve essere memorizzata nella cache condivisa.

no-cache. Evita che la risposta venga memorizzata in cache. SOLO in fase di risposta è possibile scrivere no-cache="field-name", dove field-name è il nome di un campo di intestazione che non si vuole memorizzare in cache. In pratica, quando una risposta (ad es. una pagina) viene memorizzata in cache, vengono memorizzati anche i suoi campi di intestazione. Se uno di quei campi è “Set-Cookie” e non vogliamo che venga memorizzato in cache basterà scrivere no-cache="Set-Cookie". In tal modo la pagina verrà comunque memorizzata in cache senza il campo di intestazione “Set-Cookie”. L’utilità? Dato che “Set-Cookie” crea un cookie, memorizzandolo con la pagina, quando si riutilizzerà la versione in cache verrà creato nuovamente il cookie.

no-store. Evita che la risposta venga memorizzata permanentemente nella memoria non-volatile. Questa direttiva si applica a qualsiasi tipo di cache (condivisa e non). La sua utilità consiste nel fatto che si impedisce la memorizzazione di vecchie versioni di pagine e documenti che vengono costantemente aggiornati.

s-maxage. Specifica il periodo (in secondi) dopo il quale devono essere aggiornate le risposte nella cache condivisa. Questa direttiva sovrascrive la direttiva max-age e il campo di intestazione expires.

max-age. Indica che il client è disposto ad accettare una risposta con un periodo (in secondi) maggiore di quello specificato. Se non è specificata la direttiva max-stale, il client non accetterà una risposta datata.

min-fresh. Indica che il client è disposto ad accettare una risposta che sia aggiornata almeno a un dato periodo (in secondi).

max-stale. Indica che il client è disposto ad accettare una risposta che supera la sua scadenza di un certo numero di secondi.

only-if-cached. Consente di caricare un contenuto solo se in cache è presente una sua versione, altrimenti non viene restituita alcuna risposta. Questa direttiva è utile nelle reti particolarmente lente.

must-revalidate. Poichè una cache può essere configurata in modo che ignori il tempo di scadenza di una risposta, questa direttiva consente di forzare l’aggiornamento di una risposta già memorizzata in cache. Questa direttiva viene sempre rispettata dal browser.

proxy-revalidate. Ha gli stessi effetti di must-revalidate, ma solo sulla cache condivisa.

no-transform. Evita che una cache intermedia (ad es. di un proxy) manipoli la risposta per risparmiare risorse. Infatti può succedere che un proxy comprima un’immagine per risparmiare spazio. Questa direttiva è utile nel caso di immagini da trasmettere fedelmente (ad es. in campo medico) in cui ogni pixel deve rimanere al suo posto.

Expires

Indica una data (con l’ora) a partire dalla quale la risposta memorizzata in cache deve essere considerata “vecchia”, quindi essere aggiornata.

La data deve essere espressa in un preciso formato definito dal protocollo HTTP. Ad esempio: Tue, 03 Nov 2007 17:30:00 GMT.

Expires: Tue, 03 Nov 2007 17:30:00 GMT

Pragma

Indica che la risposta non deve essere memorizzata in cache. L’unica direttiva è appunto “no-cache”.

In pratica esegue la stessa funzione di cache-control=”no-cache”, ma è necessario utilizzarla per mantenere la compatibilità con la versione 1.0 del protocollo HTTP.

Pragma: no-cache

ETag

Gli ETag o Entity Tag rappresentano un modo semplice ed efficiente per determinare se la risposta nella cache corrisponde a quella che si trova nel server di origine. Concretamente un ETag non è altro che una stringa che identifica univocamente una risposta memorizzata in cache.

Com’è composta la stringa? Non ha dei valori predefiniti ma deve essere creata in base a dei valori che potrebbero identificare la versione di una risposta. Generalmente si preferisce identificare le risposte in base alla data dell’ultima modifica e alla dimensione. Queste due informazioni vengono compresse in modo da formare un’unica stringa di dimensioni contenute, ad esempio utilizzando algoritmi di hashing come md5.

Gli svantaggi. L’unico svantaggio è che il formato e il valore di un ETag cambia da server a server. Se un determinato file risiede su più server nella stessa directory, con identiche dimensioni, permessi, timestamp, a seconda del server da cui si legge. La soluzione consiste nel creare il valore dell’ETag con un semplice script lato-server. In pratica, per avere dei benefici dagli ETag è necessario gestirli completamente con degli script lato-server, altrimenti è meglio non utilizzarli. Ecco un esempio di script.

ETag: "0401g4ff812fgk12gqg2g4j7"

Last-Modified

Rappresenta la data e l’ora dell’ultima modifica del file sul server d’origine nella forma, ad esempio, Tue, 03 Nov 2007 17:30:00 GMT.

Questo campo di intestazione è utile soprattutto nelle pagine dinamiche in cui vengono stampati dei dati ricavati da un database, o nei file creati dinamicamente (ad es. un foglio di stile che ne unisce 5 per evitare di avere 5 richieste http).

If-Match

Fornisce un metodo efficiente per controllare se la risposta ottenuta corrisponde a quella memorizzata in cache, utilizzando gli ETag, ed eventualmente aggiornarla. Viene anche usata per evitare modifiche accidentali sull’errata versione di una risorsa.

If-Match:* oppure If-Match:0401g4ff812fgk12gqg2g4j7

Nel primo caso, il carattere “*” è un carattere speciale e il campo fa corrispondere tutti i componenti di una risposta.

Nel secondo caso, il campo di intestazione fa corrispondere l’ETag con la stringa specificata.

If-None-Match

Fornisce un metodo efficiente per controllare se la risposta ottenuta corrisponde a quella memorizzata in cache, utilizzando gli ETag, ed eventualmente aggiornarla.

Al contrario di If-Match non si deve avere la corrispondenza con l’ETag confrontato o con il carattere “*”.

If-None-Match:* oppure If-Match:0401g4ff812fgk12gqg2g4j7

If-Modified-Since

Fornisce un metodo automatico per aggiornare la versione in cache di una risposta che non è stata modificata da una certa data (e ora) nel formato: Tue, 03 Nov 2007 17:30:00 GMT. Se la risposta è stata modificata a partire dalla data specificata si effettua l'aggiornamento della versione in cache, altrimenti viene restituita la versione memorizzata in cache.

If-Modified-Since: Sat, 12 Oct 2008 20:12:00 GMT

If-Unmodified-Since

Fornisce un metodo automatico per aggiornare la versione in cache di una risposta che non è stata modificata da una certa data (e ora) nel formato: Tue, 03 Nov 2007 17:30:00 GMT. Se la risposta NON è stata modificata a partire dalla data specificata si effettua l'aggiornamento della versione in cache, altrimenti viene restituita la versione memorizzata in cache.

If-Unmodified-Since: Sat, 12 Oct 2008 20:12:00 GMT

If-Range

Se la versione in cache di una risposta è parziale, questo campo di intestazione permette di ottenere solo la parte mancante. La condizione fallisce se la risorsa richiesta è stata modificata. In questo caso sarà effettuata una seconda richiesta per ottenere una risposta completa che aggiorni la versione memorizzata in cache.

If-Range: Sat, 12 Oct 2008 20:12:00 GMT

If-Range: 0401g4ff812fgk12gqg2g4j7

Nel primo caso si confronta la data dell’ultima modifica, mentre nel secondo caso si confronta la stringa dell’ETag.

Come utilizzare i campi di intestazione

ThinkingIn questo paragrafo non troverai una ricetta pronta per gestire la cache perché non so quali sono le tue esigenze. Leggi attentamente il paragrafo precedente per decidere le operazioni da effettuare in ogni pagina e risorsa del tuo sito.

Il mio consiglio è quello di analizzare i contenuti delle tue pagine (attuali e futuri) e decidere se memorizzare in cache una particolare risorsa, come gestire la versione della cache, il tempo di validità, ecc.

Se nel paragrafo precedente alcuni punti sono spiegati male, manca qualcosa o ci sono errori  fammelo sapere e correggerò tutto al più presto.

Ci sono tre metodi per impostare i campi di intestazione:

  1. impostando il tag <meta>
  2. all’interno del proprio codice lato-server (php, asp, cgi, ecc.)
  3. configurando il web server Apache tramite il file .htaccess o il file principale httpd.conf

1. Impostare i tag <meta>

Sicuramente conoscerai già il tag <meta>. Probabilmente l’avrai utilizzato per inserire description e keywords nelle tue pagine web, per migliorare l’indicizzazione del tuo sito da parte dei motori di ricerca.

Per ogni campo di intestazione che decidi di utilizzare devi:

  • creare un tag <meta> con gli attributi “http-equiv” e “content”
  • scrivere il nome del campo nell’attributo ”http-equiv”, rispettando le lettere maiuscole e minuscole
  • scrivere il valore del campo nell’attributo “content”
Esempi

<meta http-equiv="Cache-Control" content="no-cache" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="Tue, 03 Nov 2007 17:30:00 GMT" />

2. Il codice lato-server

Ogni linguaggio di programmazione ha la sua funzione per inviare un campo di intestazione.

Al momento l’unico linguaggio che conosco è PHP, con cui basterà scrivere header("Cache-Control: no-cache"); .

I campi di intestazione vanno scritti prima di qualsiasi output sulla pagina, altrimenti si verifica un errore che in sostanza dice “impossibile modificare l’intestazione – gli header sono stati già inviati”.

Tutto qui? In teoria non ci sarebbe altro… Posso solo aggiungere delle situazioni in cui diventa fondamentale utilizzare la funzione header.

Combinare più fogli di stile

Per diminuire le richieste http è una buona abitudine combinare più fogli di stile in uno solo. Si potrebbe fare manualmente, ma se in futuro vorrai effettuare delle modifiche dovrai modificare i singoli file e ricombinarli oppure modificare il file grande con la difficoltà di aver a che fare con centinaia di righe di codice.

Il metodo è quello di creare un file .css in cui inserire uno script php che permetta di stampare al suo interno tutti i file .css da te specificati. Dovrai inoltre impostare Apache affinché processi i file .css come file .php .

Per file dinamici di questo tipo sarà necessario richiamare più volte la funzione header all’inizio del file in modo da inviare i campi di intestazione riguardanti la gestione della cache.

Questo argomento farà parte del prossimo articolo su come combinare e ottimizzare immagini, css e script.

Ecco un semplice script php.

< ?
$files = array("css1.css","css2.css");
$mtime = 0;
$this_mtime = 0;
ob_start();
foreach($files as $file)
{
	if(file_exists($file))
	{
		include($file); /* includo il file */
		$this_mtime = filemtime($file); /* leggo la data dell'ultima modifica */
		if($mtime < $this_mtime) $mtime=$this_mtime;
	}
}
$lenght = ob_get_length(); /* lunghezza del contenuto */
$content = ob_get_contents(); /* il contenuto nella variabile $content da stampare successivamente */ ob_end_clean();

/* Headers */
header("Content-Type: text/css");
header("Last-Modified: ".date("D, d M Y H:i:s",$mtime)." GMT");
header("Content-Length",$lenght);
header("ETag: ".md5("compressed.css".$lenght.$mtime)); /* il file si chiama compressed.css */
header("Cache-Control: max-age=345600");

/* Stampo il contenuto */
echo $content;
?>
  • per calcolare l’ultima modifica da inviare nel campo di intestazione “Last-Modified” sarà quella del file che è stato modificato più recentemente
  • nell’ETag inserisco anche il nome del file per aumentare l’univocità dell’ETag

Come ultima operazione inserire nel file .htaccess la riga:

AddHandler application/x-httpd-php .css

Questa riga fa in modo che Apache processi i file css come file php.

Pagine dinamiche e database

Quando una pagina “dinamica” ha sempre gli stessi dati per diversi giorni è importante fare in modo che un utente, a partire dalla seconda visita, non ricarichi una nuova versione di quella pagina ma legga la versione memorizzata in cache.

Nei cms, come in Wordpress, c’è una netta separazione fra template e codice. In alcuni non è possibile creare un template per una singola pagina per altri, come Wordpress, si. Tuttavia, secondo me, è totalmente inutile creare un template per scrivere solo i tag <meta> e avere una gestione personalizzata della cache per quella pagina. Per questo motivo conviene inviare i campi di intestazione all’interno del codice.

Una prima idea è quella di definire delle condizioni per cui dei record restituiti dal database devono essere considerati “vecchi”, e in base a queste ed altre condizioni inviare gli opportuni valori dei campi di intestazione.

3. Configurare il web server Apache

Apache ServerPer gestire la cache con Apache è necessario caricare i moduli mod_expires e mod_headers.

Caricare i moduli
  • cerca e apri il file httpd.conf
  • individua la lunga lista di “mod_…”
  • individua le righe con “mod_expires” e “mod_header”
  • elimina (se c’è) il carattere “#” che si trova prima del nome dei moduli che vuoi attivare
  • riavvia il server Apache

A questo punto, nel file .htaccess bisogna definire le regole che consentono di gestire la cache a seconda del tipo o estensione dei file richiesti durante le connessioni http.

Il modulo mod_expires

Per conoscere meglio questo modulo ti consiglio di andare a leggere la guida ufficiale di Apache (in inglese): http://httpd.apache.org/docs/2.2/mod/mod_expires.html.

Il modulo mod_headers

Per conoscere meglio questo modulo ti consiglio di andare a leggere la guida ufficiale di Apache (in inglese): http://httpd.apache.org/docs/2.2/mod/mod_headers.html.

Gestione della cache in base all’estensione
ExpiresActive On
ExpiresDefault A300
<FilesMatch ".html$">
	Expires A86400
</FilesMatch>
<FilesMatch ".(gif|jpg|png|js|css)$">
	Expires A2592000
</FilesMatch>
  • la prima riga (ExpiresActive) attiva il modulo “mod_expires”
  • la seconda riga (ExpiresDefault) imposta un valore di default del campo di intestazione “Expires” pari a 300 secondi
  • il primo blocco <FilesMatch> fa in modo che tutti i file html abbiano il campo di intestazione “Expires” con il valore 86400 secondi
  • il secondo blocco <FilesMatch> fa in modo che tutti i file gif, jpg, png, js, css abbiano il campo di intestazione “Expires” con il valore 2592000 secondi
  • la lettera A indica che il valore viene impostato dopo l’accesso al file, mentre la lettera M imposterebbe il valore dopo la modifica al file

Svantaggi. Spesso capita che alcuni file, benché siano dello stesso tipo, abbiano estensioni diverse. Ad esempio, le immagini con una compressione Jpeg possono avere l’estensione jpg oppure jpeg. Quindi se capitasse un file jpeg non si avrebbe la corrispondenza.

Gestione della cache in base al tipo MIME

Per assicurarci di individuare tutti i file di un certo tipo è necessario leggere il loro tipo MIME.

ExpiresActive On
ExpiresDefault A300
ExpiresByType text/css "access plus 1 day"
ExpiresByType text/javascript "access plus 3 days"
ExpiresByType image/png "access plus 2 months"

Forzare l’aggiornamento dei componenti

Se si utilizzano dei componenti che devono essere sempre aggiornati spesso non basta scrivere i campi di intestazione "Cache-Control: no-cache" e "Pragma: no-cache". Esistono infatti prove documentate sul fatto che a volte questi campi vengono ignorati dai browser.

Quando utilizzavo un script captcha notavo che non si aggiornava l’immagine, il che era davvero un problema in quanto se l’utente sbagliava il codice doveva ricaricarsi la pagina con una nuova immagine.

La soluzione consiste nello scrivere l’indirizzo dell’immagine con un elemento dipendente dal tempo. Quindi, invece di scrivere:
<img src="myimage.jpg" alt="La mia immagine" />

si cambierà l’indirizzo in:
<img src="myimage.jpg?<? echo time(); ?>" alt="La mia immagine" />
dove la funzione time() restituisce data e ora attuali in numeri interi (ad es. 11022103710).

Nel caso si utilizzi l’immagine come sfondo, anziché scrivere:
<div style="background:#000 url('img/blackback.png') no-repeat left bottom"></div>

si dovrà modificare l’indirizzo in:
<div style="background:#000 url('img/blackback.png?<? echo time(); ?>') no-repeat left bottom"></div>

Uno dei possibili svantaggi sta nel fatto che non tutti i file possono essere processati con il compilatore php. Se vuoi che un file .js (javascript) o .css (foglio di stile) venga processato come un file php basterà aggiungere al file .htaccess le seguenti righe:

AddHandler application/x-httpd-php .css
AddHandler application/x-httpd-php .js

Per concludere, scrivendo questo articolo ho scoperto un mondo riguardo la cache e la sua gestione, ed ho capito che gestire adeguatamente la cache permette di ottimizzare notevolmente il caricamento delle pagine di un sito web.

Come utilizzavi la cache fino ad oggi? Ti limitavi a scrivere i tre tag <meta> o avevi già pensato di iniziare a utilizzare la cache più seriamente? Ti sembra importante o è solo una mia impressione? L’articolo è scritto bene o manca qualcosa?

Non perdere il prossimo articolo: “Ridurre le richieste HTTP (parte 2): combinare e ottimizzare immagini, script e css”.

Crediti

Articoli correlati
Articoli casuali (stesse categorie)
Commenti
Trackbacks
.1
8 Maggio 2009 alle 09:04

Davvero un bell’articolo, completo e chiaro, un ottima lettura! Complimenti!

.2
8 Maggio 2009 alle 12:39

@Mauro Accornero: Grazie! Sono contento che si capisca… Pubblicherò il prossimo articolo (“Ridurre le richieste HTTP (parte 2): combinare e ottimizzare immagini, script e css”) domenica o al massimo lunedì.

.3
11 Maggio 2009 alle 19:39

Alcune anticipazioni sul prossimo articolo.

Sono in ritardo con la seconda parte… Dovrei farcela per domani o mercoledì.

Gli argomenti che tratterò sono questi:
- combinare le immagini
- lo schema data:URL
- tecnica degli sprite css e ottimizzazione
- ottimizzare le immagini
- script e servizi online per ottimizzare le immagini e generare immagini sprite
- migliorare la scrittura di script e css
- combinare script e css
- comprimere script e css
- rimuovere e prevenire script duplicati
- offuscare il codice di script e css

Mi dispiace non essere abbastanza veloce a pubblicare gli articoli, ma il blog è nato da poco quindi mi serve un po’ di tempo per decidere come muovermi.

Ringrazio tutti quelli che mi leggono e mi seguono.
Grazie per l’incoraggiamento! :-)

.4
Domenico Sgarbossa
12 Novembre 2009 alle 15:45

@Giacomo:
Grande articolo Giacomo!
l’unica cosa che mi sento di farti presente è che la presenza di qualche esempio in più gioverebbe alla comprensione del tutto nonchè darebbe un aiuto più pratico a chi approccia questo tipo di problemi.
Complimenti!

.5
anedoto
8 Dicembre 2009 alle 17:43

non fa esempi perché é un’articolo copiato non capisce il contenuto..

.6
8 Dicembre 2009 alle 18:26

@Domenico Sgarbossa: sono d’accordo con te! Più in là lo riscriverò meglio e con più esempi. Non ce ne sono tanti per una pura questione di spazio. Avrei dovuto spezzarlo e approfondire meglio ogni aspetto. Lo farò! Grazie per il consiglio. ;-)

@anedoto: dimmi da dove l’ho copiato! :-) E’ uno dei miei primi post. Forse non sarà scritto molto bene… e su questo puoi anche avere ragione. Non sono nato scrittore! Sto solo condividendo le mie conoscenze sperando che siano utili a qualcuno. Lo so, devo migliorare. Ci sto lavorando… :-)

.7
13 Febbraio 2010 alle 13:02

Complimenti per l’articolo, veramente spettacolare.
Ti chiedo un aiuto, la mia header di risposta è questa:
Date: Sat, 13 Feb 2010 10:51:31 GMT
Server: Apache/2.2.14 (Unix) mod_ssl/2.2.14 OpenSSL/0.9.8e-fips-rhel5 DAV/2
X-Powered-By: PHP/5.2.11
P3P: CP=”NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM”
Content-Encoding: gzip
X-Content-Encoded-By: Joomla! 1.5
Expires: Mon, 1 Jan 2001 00:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=1, private, must-revalidate
Pragma: no-cache
Last-Modified: Sat, 13 Feb 2010 10:51:32 GMT
Vary: User-Agent
Keep-Alive: timeout=1, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8

200 OK

Secondo te va bene o c’è qualcosa di sbagliato?
Grazie mille

Stefano

.8
13 Febbraio 2010 alle 15:33

Mi dovresti specificare il tuo obiettivo… :) Per esempio: vuoi memorizzare la pagina nella cache o vuoi che si carichi ogni volta?

Un’altra cosa… Questa risposta http, a quale elemento è relativa? Alla pagina? Te lo chiedo perché il formato delle risposte http è uguale per la maggior parte degli elementi caricati. Fammi sapere! ;)

.9
13 Febbraio 2010 alle 15:57

La risposta è della home page del mio sito fatto con Joomla volevo sapere se riuscivi a capire da quei codici se era attiva la compressione gzip, gli expires header e altre cose che servono a velocizzare il caricamento della pagine.
Grazie mille

stefano

.10
13 Febbraio 2010 alle 19:14

Sicuramente la compressione gzip è attiva (vedi “Content-Encoding: gzip”).

Date: Sat, 13 Feb 2010 10:51:31 GMT
Expires: Mon, 1 Jan 2001 00:00:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=1, private, must-revalidate
Pragma: no-cache

Da questi campi si nota che Joomla fa in modo che la pagina (cioè il codice html) non venga mai memorizzata in cache e quindi che venga ricaricata sempre. Beh, è un comportamento abbastanza normale per un cms…

Il fatto che il codice html venga ri-processato ad ogni visita della pagina di sicuro non velocizza la navigazione sul sito! :)

Tuttavia avendo a che fare con un cms questa è la soluzione migliore. Infatti ad ogni caricamento il cms si occupa di eseguire un po’ di codice php ad esempio per stampare la lista di commenti di un post, gli articoli più letti, ecc. Se memorizzassi la pagina dell’articolo in cache, un “vecchio” visitatore ritornando sull’articolo potrebbe non vedere i nuovi commenti! Quindi ti conviene lasciare il comportamento delle pagine così com’è.

Dovresti invece intervenire sugli elementi più pesanti…

- Ridurre il numero di script (css e js), magari inserendo all’interno di un unico file css il contenuto di tutti i tuoi file css
- Ridurre la dimensione delle immagini
- Regolare il comportamento delle immagini e degli script riguardo la cache con Apache (se i moduli necessari sono abilitati sul tuo server)
- Utilizzare i css sprites (ti migliorano tantissimo le prestazioni)
- Utilizzare qualche modulo o plugin per joomla che gestisca la cache del browser e non (vedi http://wordpress.org/extend/plugins/wp-super-cache/)

Puoi partire da questi suggerimenti generali.

Analizza meglio le prestazioni dei vari elementi caricati in modo da capire meglio dove intervenire ed evitare di perdere tempo a fare tanti interventi che migliorano di pochissimo la velocità di caricamento delle pagine.

Utilizza YSlow! o ancora meglio Firebug.

Alcuni buoni suggerimenti li puoi trovare in uno degli ultimi articoli di Francesco Gavello: http://francescogavello.it/velocizzare-wordpress-la-guida-semi-definitiva-per-rendere-piu-veloce-il-tuo-blog

Ciao ciao :)

Puoi usare questi tag:   <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

ATTENZIONE. Se inserisci più di 2 link il commento verrà messo in coda, quindi non sarà visibile subito.

jblog: news e appunti per webmaster