49 votes

Arrêtez le navigateur pour faire des requêtes HTTP pour les images qui doivent rester en cache - mod_expires

Après avoir lu de nombreux articles et quelques questions ici, j'ai enfin réussi à en activant l'Apache mod_expires à indiquer au navigateur qu'il DOIT mettre les images en cache pour 1 an.

<filesMatch "\.(ico|gif|jpg|png)$">
  ExpiresActive On
  ExpiresDefault "access plus 1 year"
  Header append Cache-Control "public"
</filesMatch>

Et, heureusement, les réponses du serveur semblent correctes:

HTTP/1.1 200 OK 
Date: Fri, 06 Apr 2012 19:25:30 GMT 
Server: Apache 
Last-Modified: Tue, 26 Jul 2011 18:50:14 GMT 
Accept-Ranges: bytes 
Content-Length: 24884 
Cache-Control: max-age=31536000, public 
Expires: Sat, 06 Apr 2013 19:25:30 GMT
Connection: close
Content-Type: image/jpeg 

Eh bien, je pensais que ce serait arrêter le navigateur à télécharger et à même de renseigner le serveur sur les images pour 1 an. Mais c'est partiellement vrai: cause si vous fermez et rouvrez le navigateur, le navigateur ne prend PAS télécharger les images à partir du serveur de plus, mais le navigateur encore s'enquiert le serveur d'une requête HTTP pour chaque image.

Comment puis-je forcer le navigateur à arrêter de faire des requêtes HTTP pour chaque image? Même si ces requêtes HTTP ne sont pas suivis d'une image en cours de téléchargement, ils sont encore requêtes faites au serveur que unecessarely icrease de latence et de ralentir le rendu de la page!

Je l'ai déjà dit au navigateur qu'il DOIT conserver les images dans le cache pendant 1 an! Pourquoi ne navigateur toujours renseigner le serveur pour chaque image (même si elle ne permet pas de télécharger l'image)?!


En regardant réseau des graphiques dans FireBug (menu FireBug > Net > Images) je peux voir les différentes mise en cache des comportements (j'ai évidemment commencé avec le cache du navigateur complètement vide, j'ai forcé un cache supprimer sur navigateur à l'aide de "Effacer Tout l'Historique"):

  • Lorsque la page est chargée pour la 1ère fois toutes les images sont téléchargées (et la même chose se produit si je force un rechargement de la page en cliquant sur le navigateur à recharger la page un bouton). Cela a du sens!

  • Quand j'ai naviguer sur le site et de revenir à la même page, les images ne sont pas téléchargées à tous et que le navigateur n'a même PAS de renseigner le serveur pour les images. Cela fait sens, (et j'aimerais voir le même comportement lorsque le navigateur est fermé)!

  • Lorsque je ferme le navigateur et ouvrez-le à nouveau sur la même page, l'idiot du navigateur permet de toute façon de la requête HTTP au serveur une fois par image: il n'est PAS downalod l'image, mais il fait encore une requête HTTP, c'est comme le navigateur demande au serveur sur l'image (serveur répond avec 200 OK). C'est le seul qui m'agace!

J'ai également joindre les graphiques ci-dessous si vous êtes intéressés:

enter image description here

enter image description here

EDIT: viens de tester aussi avec FireFox 11.0 juste pour s'assurer que ce n'était pas un problème de mon FireFox 3.6 être trop vieux. La même chose se passe!!! J'ai aussi testé le site Google et Stackoverflow site, ils le font à la fois d'envoyer l' Cache-Control: max-age=... mais le navigateur encore fait une requête HTTP vers le serveur pour chaque image une fois que le navigateur est fermé et ouvert de nouveau sur la même page, après la réponse du serveur au navigateur de ne PAS télécharger l'image (comme je l'ai expliqué ci-dessus), mais il est quand même sacrément la demande qui augmente le temps de voir page.

EDIT2: et retrait de l' Last-Modified - tête comme suggéré ici, ne résout pas le problème, elle ne fait aucune différence.

28voto

Jason Buberel Points 1342

Le comportement que vous voyez est le but, comportement spécifié:

Tous les navigateurs modernes va envoyer des requêtes HTTP vers le serveur pour chaque élément de la page affichée, indépendamment de l'état de cache. C'était une décision de conception faite à la demande de services web (en particulier les réseaux de publicité) pour s'assurer que les serveurs HTTP ont été en mesure de maintenir des dossiers chaque affichage de chaque élément.

Si les navigateurs ne pas faire ces demandes, le serveur ne serait jamais avisé qu'une image a été affiché à l'utilisateur. Pour les réseaux de publicité, ce serait catastrophique. Dès le début, des réseaux de publicité "piratage", leur façon de contourner ce problème en servant la même annonce image à l'aide de généré de façon aléatoire des noms (ex: "coke_ad_1_98719283719283.gif'). Toutefois, pour les Fai, cette pratique a provoqué une énorme augmentation des transferts de données, parce que chacun de leurs utilisateurs a été re-téléchargement de ces identiques ad images, sans passer par une mise en cache/proxy les serveurs du fournisseur d'accès internet était d'exploitation.

Ainsi, une trêve a été atteint: les Navigateurs ne toujours envoyer des requêtes HTTP, même pour les nations unies-expiré éléments mis en cache. Serveurs de répondre avec HTTP 304 codes d'état ("non modifié"). Cela permet aux serveurs d'enregistrer le fait que l'image est affichée au client. En conséquence, les réseaux de publicité généralement arrêté à l'aide de randomisée image noms de contourner le réseau de serveurs de cache.

Cela a donné réseaux ad ce qu'ils voulaient - un enregistrement de chaque image affichée - et il a donné les Fai ce qu'ils voulaient - cache-pouvoir des images et du contenu statique.

C'est pourquoi il n'y a rien que vous pouvez faire pour empêcher les navigateurs à partir de l'envoi de requêtes HTTP pour la mise en cache des éléments de la page.

17voto

Oliver Kurmis Points 106

Vous utilisiez le mauvais outil pour analyser les demandes.

Je recommanderais les en-têtes Live HTTP très utiles de l'extension Firefox pour que vous puissiez voir ce qui se passe réellement sur le réseau.

Et juste pour être sûr, vous pouvez ssh / putty votre serveur et faire quelque chose comme

 tail -f /var/log/apache2/access.log
 

12voto

chugadie Points 323

Il y a une différence entre "recharger" et "rafraîchissant". Juste de naviguer vers une page avec les boutons précédent et suivant permettent généralement de ne pas initier de nouvelles requêtes HTTP, mais plus spécifiquement appuyant sur F5 pour actualiser la page entraîne le navigateur pour vérifier son cache. Ce navigateur est dépendante, mais semble être la norme pour FF et Chrome (c'est à dire les navigateurs qui ont la capacité de regarder facilement leur trafic réseau). Pressant F6, entrez devrait se concentrer la barre d'adresse URL et puis "go", ce qui devrait recharger la page, mais pas un double contrôle de l'actif sur la page.

7voto

Peter Lundsby Points 41

Si je force une actualisation avec F5 ou F5 + Ctrl, une demande est envoyée. Toutefois, si je ferme le navigateur et saisis à nouveau l'URL, AUCUN reqeust n'est envoyé. La façon dont j'ai testé si une requête est envoyée ou non consistait à utiliser des points d'arrêt sur la requête begin sur le serveur, même si une requête n'était pas envoyée, il apparaît toujours dans Firebug comme ayant attendu 7 ms, alors méfiez-vous-en.

6voto

symcbean Points 27412

Ce que vous décrivez ici ne tient pas compte de mon expérience. Si le contenu est servi avec un no-store ou vous faire une actualisation explicite, alors oui, je m'attends à revenir vers le serveur d'origine sinon il doit être mis en cache à travers le redémarrage du navigateur (en supposant qu'il est autorisé et peut écrire un fichier de cache).

En regardant vos chutes d'eau dans un peu plus en détail (ce qui est difficile, car ils sont un peu petite et floue) le navigateur semble être en train de faire exactement ce qu'elle devrait - il a des entrées pour les images, mais ce sont juste de chargement à partir du cache local pas à partir du serveur d'origine - cochez la case 'Date' en-tête de la réponse (pourquoi pensez-vous que c'est la prise de millisecondes au lieu de secondes?). C'est pourquoi ils sont colorés différemment.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X