Sempre più spesso, nel mondo dello sviluppo web, si sente parlare di aumento delle performance, dimunuzione delle richieste HTTP, caching di contenuti dinamici, compressione di immagini e altre tecniche orientate all’allegerimento delle pagine di un sito e all’aumento della visualizzazione sul computer del nostro caro visitatore.
Sicuramente una condizione ottimale per ottenere prestazioni migliori della propria web app o del proprio sito web è impostare il cosidetto Far Future Expire Header degli elementi prensenti nelle pagine e delle pagine stesse.
In questo post cercherò di descrivere alcune tecniche per impostare tale condizione.
Cito dal sito di YSlow:
Web page designs are getting richer and richer, which means more scripts, stylesheets, images, and Flash in the page. A first-time visitor to your page may have to make several HTTP requests, but by using the Expires header you make those components cacheable. This avoids unnecessary HTTP requests on subsequent page views. Expires headers are most often used with images, but they should be used on all components including scripts, stylesheets, and Flash components.
Quindi in pratica che fa?:-)
L’Expire Header definisce la scadenza dell’oggetto che il browser preleva dal server e deposita nella cache del client. Impostando la “data di scadenza” ad un periodo molto lontano (Far Future per l’appunto) diciamo al browser di non richiamare più tale componente durante le succesive visite alla pagina che lo conteneva, rendendo di fatto la navigazione più veloce. Inoltre, applicando questa tecnica ad elementi comuni a tutte le pagine (es: background o file javascript o file css) l’utente usufruirà dei benefici di questa tecnica fin dalla seconda pagina che andrà a visualizzare sul nostro sito.
Vediamo come fare.
Tramite l’uso di .htaccess (Apache)
<FilesMatch "\.(ico|pdf|flv|jpg|jpeg|png|gif|js|css|swf|php|html|htm|php4|php5)$"> Header set Expires "Thu, 2 Feb 2010 20:00:00 GMT" </FilesMatch>
con l’istruzione FileMatch indichiamo a quale tipo di file applicare le regole all’interno del blocco di codice e con “Header set Expires” andremo a dire ad Apache di servire il contenuto indicato con una data di scadenza molto lontana. Nell’esempio ho usato il 2 Febbraio 2010, alle 8 di sera.
Tramite le impostazioni di IIS 6.0
- Aprite il pannello di controllo di Internet Information Services (IIS).
- Espandete “LocalMachine” sul pannelo di sinistra e succesivamente cliccate su Web Sites
- Click con il tasto destro sul sito interessato e selezionate Properties.
- Nel tab HTTP Headers, attivate la checkbox “Enable Content Expiration” e succesivamente selezionate l’opzione “Expire On”. e impostare il 2 Febbraio 2010 alle 8 di sera
- Riavviate tutti i servizi IIS.
Con PHP
File far_future_loader.php
<?php header("Content-type: text/javascript; charset: UTF-8"); header("Cache-Control: must-revalidate"); header("Expires: " . gmdate("D, d M Y H:i:s",time() + (60 * 60 * 24 * 3)) . " GMT"); include(dirname(__FILE__).'/scripts.js'); ?>
con il codice sopra potete, ad esempio, raggruppare tutti i vostri file javascript in un unico grande file .php, modificare l’header Content-type in modo che venga interpretato correttamente dal browser come text/javascript e poi modificarne a piaciemento la deata di scandenza.
Successivamente nell’header delle vostre pagine, anzichè includere i singoli file javascript con l’istruzione:
<script type="text/javascript" src="js/scripts.js"></script>
userete
<script type="text/javascript" src="js/far_future_loader.php"></script>
Potete usare il file far_future_loader.php per ogni tipo di file, semplicemente cambiano il Content-type dei file che andrete ad includere, ad esempio, se volete averne uno anche per i file .css dovrete scrivere:
<?php header("Content-type: text/css; charset: UTF-8"); header("Cache-Control: must-revalidate"); header("Expires: " . gmdate("D, d M Y H:i:s",time() + (60 * 60 * 24 * 3)) . " GMT"); include(dirname(__FILE__).'/style.css'); ?>
e successivamente nell’header delle vostre pagine, esattamente come avete fatto per il file javascript, sostituirete l’istruzione:
<link rel="stylesheet" href="css/style.css" type="text/css" />
con
<link rel="stylesheet" href="css/far_future_loader.php" type="text/css" />
Con ASP
la procedura è identica a quella per PHP con la sola differenza che in ASP gli header si setttano con i seguenti comandi:
<% Response.CacheControl = "must-revalidate" %> <% Response.Expires = -1 %>
Con JSP (Tomcat)
Grazie a Byron Tymvios su jGuru
E’ possibile ottenere l’identico risultato avuto con PHP o ASP tramite i filtri. Ad esempio:
package com.xyz
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class CacheFilter implements javax.servlet.Filter {
FilterConfig filterConfig = null;
public void init(FilterConfig filterConfig){
this.filterConfig = filterConfig;
}
public void doFilter(ServletRequest req,
ServletResponse res,
FilterChain chain)
throws IOException, ServletException {
String sCache = filterConfig.getInitParameter("cache");
if(sCache != null){ ((HttpServletResponse)res).setHeader("Cache-Control", sCache);
}
chain.doFilter(req, res);
}
public void destroy(){
this.filterConfig = null;
}
}e poi impostare nel file web.xml il filtro per ogni contenuto desiderato. Ecco l’esempio per i file .jpg:
<filter>
<filter-name>Cache</filter-name>
<filter-class>com.xyz.CacheFilter</filter-class>
<init-param>
<param-name>cache</param-name>
<param-value>public, max-age=2592000</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>Cache</filter-name>
<url-pattern>*.jpg</url-pattern>
</filter-mapping>è tutto ![]()
nella prossimo post parleremo degli ETag.
Giovanni



2 Comments
1 Oct 19, 2009 at 1:48
/MePoune
:*
Cercavo un metodo utilizzabile su un IIS sul quale non ho accesso al pannello di controllo (ahhh senza .htaccess + php che minifizzano basandosi su $_SERVER[DOCUMENT_ROOT] mi sento perso), ho manipolato il tuo php per i miei scopi in questo modo
in modo da impostare in più la compressione e il last-modified [che non cambi ogni minuto secondo e continuamente come l'expire, ma che cambi (...) - l'ETag non c'è per i non-hmtl]
Sul must-revalidate sono diviso
Arrivo tardi (hai pubblicato January 14th, 2009, vedo) ma grazie
2 Oct 19, 2009 at 1:53
/MePoune
(ultimo tentativo)
?php
ob_start(“ob_gzhandler”);
header(“Content-type: text/css; charset: UTF-8″);
header(“Expires: ” . gmdate(“D, d M Y H:i:s”,time() + (60 * 60 * 24 * 3)) . ” GMT”);
header(“Last-Modified: ” . gmdate(“D, d M Y 19:02:05″,time() – (60 * 60 * 24 * 3)) . ” GMT”);
include(dirname(__FILE__).’/default.css’);
include(dirname(__FILE__).’/footer.css’);
include(dirname(__FILE__).’/pushup.css’);
?
Leave a Comment