<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Performance web &#187; expires</title>
	<atom:link href="http://performance.survol.fr/avec/expires/feed/" rel="self" type="application/rss+xml" />
	<link>http://performance.survol.fr</link>
	<description>Quelques mots pour des sites web rapides</description>
	<lastBuildDate>Fri, 18 Jun 2010 12:47:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Petit point sur les caches</title>
		<link>http://performance.survol.fr/2009/06/petit-point-sur-les-caches/</link>
		<comments>http://performance.survol.fr/2009/06/petit-point-sur-les-caches/#comments</comments>
		<pubDate>Wed, 10 Jun 2009 10:00:39 +0000</pubDate>
		<dc:creator>Éric</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[cache-control]]></category>
		<category><![CDATA[expiration]]></category>
		<category><![CDATA[expires]]></category>
		<category><![CDATA[http]]></category>
		<category><![CDATA[proxy]]></category>

		<guid isPermaLink="false">http://performance.survol.fr/?p=515</guid>
		<description><![CDATA[Votre page peut-elle être mise en cache par le navigateur ? voyons ce qu&#8217;il en est en théorie avec HTTP 1.1 (en pratique le navigateur fera toujours ce qu&#8217;il veut, et il y a plus de couples navigateur/configuration que vous &#8230; <a href="http://performance.survol.fr/2009/06/petit-point-sur-les-caches/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Votre page peut-elle être mise en <a href="http://performance.survol.fr/2008/03/impact-du-cache-http/">cache</a> par le navigateur ? voyons ce qu&#8217;il en est en théorie avec <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html"><acronym title="hypertext transfer protocol" lang="en">HTTP</acronym> 1.1</a> (en pratique le navigateur fera toujours ce qu&#8217;il veut, et il y a plus de couples navigateur/configuration que vous ne l&#8217;imaginez, donc n&#8217;ayez aucune certitude).<span id="more-515"></span></p>
<h3>Les absolus</h3>
<p>Quoi que vous disiez, quoi que vous fassiez, si le serveur vous a répondu avec un code d&#8217;erreur 400, le navigateur devrait mettre en cache se résultat et ne pas refaire la même requête. C&#8217;est plutôt logique pour une requête que le serveur a considéré comme invalide.</p>
<p>Quoi que vous disiez, quoi que vous fassiez, si le code de retour était 303 ou 307, le navigateur ne devrait pas mettre en cache ce résultat. La redirection est temporaire, marquée comme telle, mettre en cache du temporaire c&#8217;est faire du permanent, donc contredire la réponse.</p>
<h3>L&#8217;heuristique</h3>
<p>S&#8217;il s&#8217;agit d&#8217;une requête de type <span lang="en">GET</span> avec un code de retour 200, 203, 206, 300, 301 ou 410, alors le navigateur ou le proxy sont encouragés à mettre en cache suivant leurs propres heuristiques. Le plus souvent la page HTML elle-même n&#8217;est pas mise en cache par défaut, mais les composants référencés par cette page sont mis en cache pour la durée de la session.</p>
<p>Il est à noter que la spécification HTTP 1.1 prévoit la fonctionnalité de retour arrière des navigateurs et incite le navigateur à réutiliser la page précédente sans la réactualiser, quand bien même elle aurait expiré. Le visiteur l&#8217;a déjà vu, il s&#8217;agit de lui représenter là où il était avant, pas de revenir sur la page actualisée.</p>
<h3>L&#8217;invalidation</h3>
<p>Quand le serveur répond à une requête <span lang="en">POST</span>, les versions en cache de cette <acronym title="uniform resource identifier" lang="en">URI</acronym> ou de celle dans les entêtes <code lang="en">Location</code> ou <code lang="en">Content-Location</code> doivent être effacés. Ceci implique immédiatement que par défaut une requête <span lang="en">POST</span> ne sera pas mise en cache.</p>
<p>La spécification HTTP 1.1 va même un peu plus loin en prenant en compte l&#8217;usage des paramètres de requêtes dans les URI. Certains utilisent ainsi des paramètres en <span lang="en">GET</span> pour réaliser des actions qui devraient être faites en <span lang="en">POST</span> (puisque provocant un changement dans l&#8217;entité résultat). Pour y palier, HTTP 1.1 demande à ce que ces requêtes (contenant un point d&#8217;interrogation dans le chemin) ne soient pas mises en cache quand bien même elles seraient faites avec le verbe <span lang="en">GET</span>.</p>
<p>Petite note : Si vous renvoyez un document avec une entête <code lang="en">Date</code> inférieure à celle qu&#8217;avait eu le navigateur la dernière fois, cette réponse ne devrait être pas mise en cache.</p>
<h3>La déclaration explicite</h3>
<p>Maintenant, hors les premiers cas absolus, les entêtes explicites ont priorité. Une <a href="http://performance.survol.fr/2008/05/prive-ou-public/">entête <code lang="en">Cache-Control</code></a> à <code lang="en">public</code>, <code lang="en">private</code>, ou <code lang="en">no-cache</code> change le comportement par défaut. Un <a href="http://performance.survol.fr/2008/10/expires-et-cache-control-une-date-limite-de-consommation-pour-vos-contenus/"><code lang="en">max-age</code> ou <code lang="en">Expires</code></a> impose un <code lang="en">cache</code> et un <code lang="en">must-revalidate</code> impose une revalidation, même si ces règles contredisent le comportement par défaut pour la ressource en question.</p>
<p>Enfin, les caches sont toujours dépendants de l&#8217;entête <code lang="en">Vary</code>, qui permet de restreindre le cache à un navigateur, ou des visteurs avec un certain cookie, etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://performance.survol.fr/2009/06/petit-point-sur-les-caches/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Expires et Cache-Control, une date limite de consommation pour vos contenus</title>
		<link>http://performance.survol.fr/2008/10/expires-et-cache-control-une-date-limite-de-consommation-pour-vos-contenus/</link>
		<comments>http://performance.survol.fr/2008/10/expires-et-cache-control-une-date-limite-de-consommation-pour-vos-contenus/#comments</comments>
		<pubDate>Wed, 01 Oct 2008 10:00:47 +0000</pubDate>
		<dc:creator>Éric</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[cache-control]]></category>
		<category><![CDATA[expiration]]></category>
		<category><![CDATA[expires]]></category>
		<category><![CDATA[http]]></category>

		<guid isPermaLink="false">http://performance.survol.fr/?p=206</guid>
		<description><![CDATA[Je parle de détails et de ce que je rencontre dans mes lectures, et j&#8217;en oublie le principal. alors voilà, si vous ne devez retenir qu&#8217;une chose c&#8217;est d&#8217;utiliser des dates d&#8217;expiration explicites sur vos contenus. Il s&#8217;agit d&#8217;informer le &#8230; <a href="http://performance.survol.fr/2008/10/expires-et-cache-control-une-date-limite-de-consommation-pour-vos-contenus/">Continuer la lecture <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>Je parle de détails et de ce que je rencontre dans mes lectures, et j&#8217;en oublie le principal. alors voilà, si vous ne devez retenir qu&#8217;une chose c&#8217;est d&#8217;<strong>utiliser des dates d&#8217;expiration explicites</strong> sur vos contenus.</p>
<p>Il s&#8217;agit d&#8217;informer le navigateur que votre contenu est valable pendant une certaine durée. Cela peut être dix minutes, une heure, un jour, un mois, ou plusieurs années. Tant que cette durée n&#8217;a pas expirée, le navigateur sait que son contenu est à jour, il peut donc éviter de le retélécharger. Vous gagnez du temps en évitant la requête HTTP et vous laissez de la place pour d&#8217;autres téléchargements. Au lieu de prendre une demi seconde, votre contenu sera lu quasiment instantanément.<span id="more-206"></span></p>
<h3>Les détails HTTP 1.0</h3>
<p>En fait tout ça c&#8217;est assez simple. En <a href="http://www.w3.org/Protocols/HTTP/1.0/spec.html">HTTP 1.0</a>, le serveur envoie avec le contenu une <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.21">entête Expires</a> avec une date au format de la <a href="http://www.freesoft.org/CIE/RFC/1123/">RFC 1123</a>.</p>
<pre>Expires: Thu, 01 Dec 1994 16:00:00 GMT</pre>
<p>Le navigateur et les proxy stockent dans le cache la ressource avec cette date. Les prochaines fois c&#8217;est le contenu sauvegardé dans le cache qui est utilisé, sans aucun appel au serveur.</p>
<p>Une fois la date dépassée, le navigateur fait de nouveau appel au serveur pour obtenir un contenu mis à jour, et éventuellement une nouvelle date d&#8217;expiration explicite. C&#8217;est normalement une requête conditionnelle qui est faite à ce niveau là donc si le contenu n&#8217;a toujours pas changé il ne sera toujours pas retéléchargé inutilement.</p>
<h3>Les détails HTTP 1.1</h3>
<p>Le gros défaut HTTP 1.0 c&#8217;est qu&#8217;en général on ne souhaite pas une date d&#8217;expiration fixe, on cherche une expiration de type « maintenant + 10 jours ». Résultat, il faut générer la date à chaque fois.</p>
<p><a href="http://www.w3.org/Protocols/rfc2616/rfc2616.html">HTTP 1.1</a> nous propose un mécanisme plus sympathique avec <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9">l&#8217;entête Cache-Control</a> dont je vous avais détaillé un des paramètres il y a quelques temps. Le paramètre qui nous intéresse ici est <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">le paramètre max-age</a>. Il prend un nombre de secondes pendant lesquelles le contenu doit être considéré comme à jour.</p>
<pre>Cache-Control: public;max-age=3600</pre>
<p>Cette directive est valable autant pour les caches partagés (proxy) que les caches personnels (navigateur). Il existe toutefois un second <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.3">paramètre s-maxage</a>, qui ne cible que les caches partagés. Le fonctionnement est similaire.</p>
<h3>J&#8217;utilise quoi ?</h3>
<p>Autant que possible, utilisez les deux. Rien n&#8217;est parfait dans ce bas monde et vous n&#8217;avez pas de garantie que la directive Cache-Control sera interprétée correctement, même si le client utilise la version 1.1 du protocole.</p>
<p>En cas de conflit le client est censé utiliser la directive Cache-Control. Mais après tout, pourquoi voudriez-vous envoyer deux informations contradictoires ?</p>
<h3>Comment ?</h3>
<p>Le plus simple sous Apache c&#8217;est <a href="http://httpd.apache.org/docs/2.0/mod/mod_expires.html">mod_expires</a>. Vous pouvez régler le comportement par défaut et par type de fichier. À chaque fois vous pouvez définir une durée pendant laquelle le contenu est considéré comme à jour, et si cette durée est à prendre à partir de la dernière modification de votre contenu ou de la date de la requête.</p>
<pre>ExpiresDefault "access plus 1 month 15 days 2 hours"
ExpiresByType image/gif "modification plus 5 hours 3 minutes"</pre>
<p><a href="http://trac.lighttpd.net/trac/wiki/Docs%3AModExpire">Pour Lighttpd le module a le même nom</a>, et la syntaxe est assez similaire :</p>
<pre class="last literal-block">$HTTP["url"] =~ "^/images/" {
     expire.url = ( "" =&gt; "access 1 hours" )
}</pre>
<h3>Sur quoi ?</h3>
<p>Ces entêtes sont pertinentes pour tout ce qui bouge peu, pas du tout, ou à une fréquence déterminée :</p>
<p>Prenez en compte au moins vos logos, vos icônes, vos images de fond, bref, ce qui ne change quasiment jamais, sans exception. Pour ces contenus vous pouvez mettre une expiration virtuellement infinie, de plusieurs années. Le jour où vous faites une modification il suffira de faire un nouveau fichier avec une nouvelle adresse publique.</p>
<p>Pour vos feuilles de style et vos javascript, même chose. Vos contenus changent plus souvent mais si vous arrivez à changer l&#8217;URL à chaque modification vous pouvez encore mettre une expiration quasi infinie. Pour changer l&#8217;adresse à chaque version vous pouvez ajouter le numéro de version dans le nom du fichier, ou ajouter un paramètre à l&#8217;url qui contient la date de dernière modification. Je ferai un billet plus complet sur le sujet plus tard.</p>
<p>Enfin, les pages HTML. Là il faut être plus fin. Toutes les pages ne sont pas pertinentes pour une expiration. Plus classiquement si à deux minutes d&#8217;intervalle il est important que le contenu change, oubliez l&#8217;expiration explicite. Par contre une bonne partie des pages peuvent avoir une expiration de quelques minutes, voire d&#8217;une ou deux heures. C&#8217;est souvent le cas des pages d&#8217;accueil et des pages principales. L&#8217;utilisateur y revient souvent lors de sa navigation. Si ces pages peuvent être instantanées, c&#8217;est un réel gain pour l&#8217;utilisateur. Si vous avez un système d&#8217;authentification sur vos pages, n&#8217;oubliez pas de <a href="http://performance.survol.fr/2008/05/prive-ou-public/">déclarer aussi le cache comme privé avec la directive Cache-Control</a>.</p>
<h3>Le bénéfice</h3>
<p>Un contenu avec une expiration explicite c&#8217;est un contenu qu&#8217;on évite de retélécharger plusieurs fois inutilement. Pour l&#8217;utilisateur c&#8217;est la sensation que le téléchargement est instantané, que l&#8217;interface et que le site réagissent immédiatement — et n&#8217;oubliez pas, <a href="http://performance.survol.fr/2008/06/a-quoi-ca-sert/">cela a une influence importante sur votre business</a>. Pour vous c&#8217;est autant de charge en moins pour votre serveur, et autant de bande passante économisée. Rien que là dessus vous pouvez économiser des sommes importantes.</p>
<p>Pour exemple, la page de Yahoo! met environ deux secondes tout compris à charger avec plus de 40 requêtes HTTP, ce qui en soit est assez honorable face au reste du web. Par contre sur cette quarantaine de requêtes HTTP, plus des trois quarts ont une expiration explicite comme détaillé plus haut. Le résultat c&#8217;est que ma seconde visite ne télécharge plus que 7 composants externes. Ma bande passante est libre pour autre chose et ma page se charge bien plus rapidement. Suivant les publicités sur la page, c&#8217;est entre une demi seconde et une seconde que je gagne. Pour une page d&#8217;accueil qui ne doit surtout pas donner une impression de lenteur, c&#8217;est significatif et même important.</p>
]]></content:encoded>
			<wfw:commentRss>http://performance.survol.fr/2008/10/expires-et-cache-control-une-date-limite-de-consommation-pour-vos-contenus/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
	</channel>
</rss>
