Différence entre "last-modified" et "if-modified-since"

Nouveau WRInaute
Bonjour,

Je suis en train de revisiter le référencement sur mon site , j'ai une question concernant la différence entre "last-modified" et "if-modified-since" ?
Lequel est le plus performant pour Google et pour mon site?
Merci pour vos réponses

Cordialement,
André
 
WRInaute accro
Last-Modified est envoyé du serveur au client. If-Modified-Since est envoyé du client au serveur (qui répondra en général par un 200 avec le contenu si ça a changé, ou par un 304 sans contenu s'il n'a pas changé).

Jacques.
 
Nouveau WRInaute
Merci pour ta réponse.
Si je comprends bien, les deux ont les même fonctions. Si last modfied est envoyé par le serveur, je pense que c'est celui que google préfère?
 
WRInaute passionné
Toi tu mets last modified avec une datte, et le client qui vient visiter ton site envoie if modified since à ton serveur. Si ta datte est plus récente que la date du cache du client, il retélécharge la page sinon il affiche son cache. Moi j'ai pas cet header c'est grave ?
 
WRInaute passionné
Oui je viens de lire un article similaire (merci de m'avoir mis sur la voie) Je pense que cela est bon pour Google, d'ailleurs c'est précisé dans les conseils aux webmasters, je n'avais pas vu. Comme je n'avais pas cet entête, je pense que Google visitait plusieurs fois les mêmes URLs et donc perdait du temps au lieu d'en crawler d'autre.
 
WRInaute accro
Last-Modified n'est pas vraiment fondamental (Expires ou Cache-Control sont nettement plus utiles), mais en l'absence de ces derniers, ça permet de donner une indication sur la fréquence de mise à jour d'un fichier, et donc de décider quand il faut retourner voir s'il a changé.

Maintenant, que le serveur connaisse la date de dernière modification (qui est donc celle envoyée dans Last-Modified) est nécessaire pour la gestion de If-Modified-Since, qui va permettre de renvoyer un 304 si le fichier n'a pas changé (et donc de ne pas renvoyer le fichier, ce qui économise de la bande passante et du boulot pour toi et les moteurs, et accélère le chargement pour les utilisateurs).

Sur des fichiers statiques (pages html, fichiers JS, CSS, images, etc.), un serveur http va généralement faire tout ça tout seul pour toi, donc tu n'as rien à faire.

Pour tout ce qui est dynamique (php, etc.), c'est plus compliqué, donc il faut en général le gérer soi-même dans son script (en récupérant HTTP_IF_MODIFIED_SINCE et en le comparant à la date de dernière modification du contenu qui va être renvoyé -- ce qui peut être plus ou moins évident à calculer: pour un blog par exemple, il ne s'agit pas forcément juste de la date du post, puisqu'il y a tout un tas de contenu "autour" qui peut changer par la suite).

Je ne suis pas sûr qu'envoyer Last-Modified soit vraiment très utile, par contre des headers Expires/Cache-Control sont appréciés (il permettent eux aussi de gagner en performances, un navigateur qui a déjà le fichier en cache ne fera même pas une requête avec un If-Modified-Since).

Jacques.
 
WRInaute passionné
Moi j'ai ça en entête est-ce que c'est bon ?

Code:
Date: Thu, 30 Sep 2010 12:58:36 GMT
Server: Apache/2.0.52 (CentOS)
X-Powered-By: PHP/4.3.9
Expires: Sun, 25 Sep 2011 20:00:00 GMT
Cache-Control: max-age=1209600, public
Content-Encoding: gzip
Vary: Accept-Encoding
Last-Modified: Sun, 26 Sep 2010 20:00:00 GMT
Content-Length: 7005
Content-Type: text/html

200 OK
 
WRInaute accro
Si le but du jeu est de dire que cette page ne changera pas pour un bon moment, et qu'un cache peut servir cette même page à tout le monde, oui. Je suis cependant un peu surpris par le fait que le max-age (14 jours) et le Expires (presque un an) ne correspondent pas vraiment...

Note que ça ne veut pas forcément dire que If-Modified-Since est géré correctement.

De façon générale, de nos jours, très souvent les pages html dynamiquement générées ne peuvent pas être mises en cache (via un Expires très court ou un Cache-Control: no-cache par exemple) parce qu'elles sont fortement personnalisées (en fonction de cookies de l'utilisateur par exemple) et actualisées (avec des éléments comme les derniers messages, le nombre de connectés, etc.). Au contraire, les fichiers "statiques" tels que les images, CSS, JS, etc. doivent avoir une expiration la plus longue possible (ce qui implique que si on veut modifier le fichier, on en crée en fait une nouvelle version avec un nouveau nom, et on référence ce nouveau nom dans les pages dynamiques).

Mais à chacun son cas particulier...

Jacques.
 
WRInaute passionné
Effectivement ce sont des fausses pages html gérées dynamiquement, j'avais mis ces entête en espérant amélioré le référencement. Il y a des parties gérées par le cookie pour le panier, la connexion etc, il faut donc que je ne mete pas en cache ces pages ? Car dans les conseils aux webmasters Google il y a écrit de vérifier que le serveur accepte bien If-modified-since. Si j'enleve mes règles dans mon htacces j'ai ceci sur mes fiches produit:
Code:
Date: Thu, 30 Sep 2010 14:59:55 GMT
Server: Apache/2.0.52 (CentOS)
X-Powered-By: PHP/4.3.9
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Encoding: gzip
Vary: Accept-Encoding
Connection: close
Transfer-Encoding: chunked
Content-Type: text/html

200 OK

C'est bon pour Google ou pas ? Je peux laissé tel quel ?
Avec l'audit Google Chrome il me dit ceci:

The following resources are missing a cache expiration. Resources that do not specify an expiration may not be cached by browsers:
pub1.png
pub2.png
pub3.png
pub4.png
bg.png
maintablebg.jpg
pixel_trans.gif
pointer_blue.gif
pointer_blue_light.gif

Pourtant j'ai bien ceci dans mon htacces à la racine:
Code:
<FilesMatch ".(js|ico|jpg|png|gif|css|pdf|txt|html)$">
Header set Cache-Control "max-age=1209600, public"
Header set Expires "Sun, 25 Sep 2011 20:00:00 GMT"
Header set ExpiresDefault "access plus 14 days"
Header set Last-Modified "Sun, 26 Sep 2010 20:00:00 GMT"
Header unset Pragma
</FilesMatch>

Merci de ton aide
 
Nouveau WRInaute
Jacques, je vous remercie pour votre aide.
Elle m'a été grandement utile dans l'utilisation des ces variables header.
Je vais suivre ton conseille et a m'atteler plus à mon cache.
Merci encore.
André
 
WRInaute accro
Oui, pour une page dynamique de ce type, mettre des Expires et Cache-control: max-age longs c'est contre-productif. Ca veut même dire que si le client revient sur la même page après avoir (par exemple) ajouté un produit à son panier, il ne le verra pas, puisque la page ne sera pas rechargée! Et pire encore, un utilisateur qui partagerait le même cache (via un proxy comme chez AOL par exemple) pourrait voir le contenu du panier de l'autre utilisateur!

En général, on fait donc tout le contraire sur ce genre de page: on met un Expires dans le passé, et un Cache-Control: no-cache, comme ça le navigateur va venir récupérer la page à chaque fois (ou au moins demander si elle a changé). C'est ce que tu obtiens maintenant.

Le If-Modified-Since doit être géré (explicitement) côté serveur, il ne suffit pas de mettre un Last-Modified ou un Expires pour que ça marche tout seul. Mais sur une page dynamique comme celle-ci, de toutes façons, tu peux presque toujours considérer que la page aura changé.

(évidemment dans certains cas on peut faire des stratégies plus complexes, avec des pages relativement statiques pour Google et des pages dynamiques pour les autres, mais c'est essentiellement pour des raisons de charge sur tes serveurs, et tu peux vite t'emmêler les pinceaux si tu ne maîtrises pas tout ça).

A l'opposé, les fichiers statiques doivent effectivement être mis en cache le plus possible. Plutôt que de mettre toutes sortes de headers "en dur" (que tu oublieras de modifier dans un an quand il expireront), je te conseille plutôt quelque chose du genre:
ExpiresActive On
ExpiresDefault "access plus 7 days"
ExpiresByType image/gif "access plus 10 years"
ExpiresByType image/png "access plus 10 years"
ExpiresByType image/jpg "access plus 10 years"
etc.
(tu as besoin de mod_expires).

Le Last-Modified sera fourni spontanément par Apache, qui gèrera aussi automatiquement If-Modified-Since pour les fichiers statiques.

Deux exemples détaillés:

Premier exemple: fichier dynamique, généré en php, avec plein de choses qui changent tout le temps (produits, panier, etc.):

Première requete:
- le client n'est jamais venu sur la page, il fait donc une requête normale
- le serveur répond avec:
Expires: (date dans le passé)
Cache-control: no-cache
- le client affiche la page, et note qu'il ne doit pas la mettre en cache

Deuxième requête pour la même page:
- le client est déjà venu, mais il n'a rien mis en cache, il faut donc une requête normale de nouveau
- le reste idem

Deuxième exemple: fichier statique

Première requête:
- le client n'est jamais venu sur la page, il fait donc une requête normale
- le serveur répond avec:
Expires: (loin dans le futur)
Cache-control: max-age=beaucoup
- le client affiche la page, et note qu'il peut la mettre en cache, avec son expiration, et la date de la requête

Deuxième requête (même fichier, dans une autre page par exemple)
- le client a déjà le fichier en cache, il ne le demande même pas au serveur

Troisième requête (même fichier, l'utilisateur a forcé un reload)
- le client a déjà le fichier en cache, mais comme il y a reload, il va demander au serveur, avec un If-Modified-Since: la date de la dernière requête
- le serveur compare le If-Modified-Since, note que le fichier n'a pas changé depuis, renvoie un 304 pour dire que le fichier n'a pas changé (et ne renvoie pas le fichier)

Jacques.
 
WRInaute passionné
Merci beaucoup Jacques pour tes réponses par-faites, j'ai tout compris !
Du coup j'ai enlevé les entêtes sur les pages dynamiques, comme ça expires dans le passé et cache-control no-cache.
Par contre, si la page change effectivement (panier, connexion etc) les images elles restent les mêmes, j'ai donc mis ceci pour ne pas retélécharger les images, j'ai l'impression que ça fonctionne car la navigation sur mon site est beaucoup plus rapide !

Code:
<FilesMatch ".(js|ico|jpg|png|gif|css|pdf|txt|html)$">
Header set Cache-Control "max-age=1209600, public"
Header set Expires "Sun, 25 Sep 2011 20:00:00 GMT"
Header set ExpiresDefault "access plus 14 days"
Header set Last-Modified "Sun, 26 Sep 2010 20:00:00 GMT"
Header unset Pragma
</FilesMatch>

Merci beaucoup encore une fois !
 
Nouveau WRInaute
Merci pour ta longue explication et surtout du temps que tu passes !!!!!
J'ai bien lu ton texte et il me permet de voir beaucoup plus clair, comme j'ai finis la gestion last modified et du if-modified-since.
Je vais m'atteler au cache.
Merci encore.
 
Nouveau WRInaute
Si je comprends bien l'historie du cache.
Pour le page statique je laisse faire le Server.
Mais pour les pages dynamique je me dois te changer.
En fait pour un site de e commerce quel cache faut il ?
Je suis un peu perdu
Car si j'ai bien compris pour une une page dynamique par exemple une fiche produit :
Nous somme le vendredi 01/10/10 :
expires : Jour-1
cache control : no contol
last modified : 30/08/10.
Ai je bien compris ?
Dois je le configurer du server ou bien de manière dynamique ( pour info IIS6 et Asp)

Merci

André
 
WRInaute accro
lambi521 a dit:
j'ai donc mis ceci pour ne pas retélécharger les images, j'ai l'impression que ça fonctionne car la navigation sur mon site est beaucoup plus rapide !

Code:
<FilesMatch ".(js|ico|jpg|png|gif|css|pdf|txt|html)$">
Header set Cache-Control "max-age=1209600, public"
Header set Expires "Sun, 25 Sep 2011 20:00:00 GMT"
Header set ExpiresDefault "access plus 14 days"
Header set Last-Modified "Sun, 26 Sep 2010 20:00:00 GMT"
Header unset Pragma
</FilesMatch>

Comme je disais plus haut, je déconseille ce ce code pour plusieurs raisons:
- le max-age et le Expires ne correspondent pas
- le Expires est "en dur", et forcément tu ne penseras pas à le mettre à jour d'ici 1 an
- le header ExpiresDefault n'existe pas, il y a confusion avec la directive ExpiresDefault
- le Last-Modified en dur ça ne sert à rien, il sera déjà trouvé et fourni par le serveur tout seul comme un grand

Utilise plutôt ExpiresDefault et ExpiresByType comme indiqué plus haut.

Jacques.
 
WRInaute accro
dedein84 a dit:
Si je comprends bien l'historie du cache.
Pour le page statique je laisse faire le Server.

Il est quand même conseillé de mettre un Expires (via ExpiresByType sur Apache) par exemple, ça permet au navigateur de ne même pas venir faire une requête parce qu'il sait que le fichier est toujours bon.

dedein84 a dit:
Mais pour les pages dynamique je me dois te changer.
En fait pour un site de e commerce quel cache faut il ?
Je suis un peu perdu
Car si j'ai bien compris pour une une page dynamique par exemple une fiche produit :
Nous somme le vendredi 01/10/10 :
expires : Jour-1
cache control : no contol
last modified : 30/08/10.
Ai je bien compris ?
Dois je le configurer du server ou bien de manière dynamique ( pour info IIS6 et Asp)

Le Expires et le Cache-Control suffisent, le Last-Modified n'a pas grande utilité. Mais je n'ai aucune idée de comment on configure ça sur IIS ou en ASP. Note qu'il n'est pas impossible que ASP ou le CMS utilisé les mette déjà d'office.

Jacques.
 
Nouveau WRInaute
Bonjour,
vous avez passé un bon we?

Voila mon header, pouvez me dire ce que vous en pensez?
Code:
Cache-Control:no-cache
Content-Encoding:gzip
Content-Type:text/html; Charset=utf-8
Date:Mon, 04 Oct 2010 08:56:21 GMT
Expires:Sun, 03 Oct 2010 08:56:20 GMT
Last-Modified:jeu., 30 sept. 2010 14:17:47 GMT
Pragma:no-cache
Server:Microsoft-IIS/6.0
Transfer-Encoding:chunked
Vary:Accept-Encoding
X-Powered-By:ASP.NET
Merci de votre aide

André
 
Nouveau WRInaute
Je te remercie pour ton aide, vraiment un grand merci.
Juste une dernière question, je me demande si pour les pages dynamiques Cache-Control:private n'est pas mieux que Cache-Control:no-cache ?

Encore un merci

André
 
WRInaute passionné
Un grand merci Jacques pour tes connaissances, toutes mes images et fichiers se mettent en cache et tous mes fichiers php se recharge à chaque fois, la navigation est beaucoup plus rapide sur mon site, plus d'erreurs dans l'audit de Google chrome et tout fonctionne parfaitement.

Merci bcp !
 
Discussions similaires
Haut