Il existe plusieurs façons de mettre en cache.
GET conditionnel
Si vous stockez ces images sur le système de fichiers et les diffusez directement via le serveur Web, vous utilisez probablement déjà le get conditionnel . Le serveur Web utilisera automatiquement les métadonnées du système de fichiers pour définir un en-tête ETAG et répondra automatiquement par «304 non modifié» si le navigateur inclut If-Modified-Since
ou en- If-Matches
têtes dans sa demande. (Tous les navigateurs le feront.)
Dans ce cas, l'image entière n'est pas renvoyée, vous économisez donc de la bande passante. Cependant, une demande GET sera toujours émise, vous aurez donc la surcharge et la latence d'une demande.
Vous pouvez diminuer légèrement le nombre de demandes au détriment de la fraîcheur du cache en ayant votre serveur Web défini des en- Cache-Control
têtes avec une public,max-age=N
valeur pour vos images. Cela signifie que les caches peuvent conserver la ressource pendant au plus max-age
secondes avant de devoir vérifier si elle est mise à jour.
Cependant, HTTP définit une seule façon d'invalider une entrée de cache, qui peut ne pas correspondre à la sémantique de votre application: si vous POSTEZ ou METTEZ sur une URL qui met à jour la photo de profil, répondez avec un en- Location: [url of photo]
tête et l'entrée de cache pour cette URL sera invalidée.
(Il s'agit du mécanisme qui vous permet de mettre en cache une page Web avec des commentaires, puis de recharger la page de force par le navigateur après que l'utilisateur a publié un nouveau commentaire. Le navigateur répondrait à un POST /comment
avec 303 See Other
et un Location: /page/with/comment
. Notez que cela n'a pas été utilisé pour fonctionner dans Firefox en raison d'un bug de longue date .)
À moins que vous n'ayez beaucoup de trafic, cette approche de la mise en cache convient.
Changer les URL
Une URL est une représentation d'une ressource, donc une autre façon de gérer la mise en cache n'est pas de changer les paramètres de cache pour la ressource, mais de créer une nouvelle ressource avec une directive "cache forever". C'est l'approche privilégiée par les "grands garçons", car elle leur permet de ne générer aucune demande supplémentaire, leur permettant d' économiser beaucoup de bande passante. L'inconvénient est qu'il nécessite une comptabilité supplémentaire.
Il existe deux techniques générales pour cela.
Chaînes de requête
Les serveurs Web ignorent les chaînes de requête lorsqu'ils servent un fichier à partir du système de fichiers. Caches, cependant, ne le font pas: /1.jpg?t=12345
et /1.jpg?t=67890
sont deux complètement différentes, sans rapport avec les ressources, même si le serveur pense qu'ils sont les mêmes.
Donc, une chose simple que vous pouvez faire est d'ajouter l'horodatage du système de fichiers en tant que chaîne de requête chaque fois que vous faites référence à une ressource dans votre html et définissez un en- Expires
tête long . Le navigateur mettra alors en cache cette ressource pour toujours et n'effectuera aucun GET tant que la chaîne de requête ne changera pas.
Un inconvénient est qu'il est difficile, voire impossible, d'indiquer au serveur Web la nouvelle URL d'un élément si vous souhaitez invalider de force un cache. Par exemple, si un navigateur a une page HTML en cache avec une /1.jpg?v=1
référence, mais qu'il est arrivé d'effacer l'entrée /1.jpg?v=1
(peut-être qu'il manquait d'espace de fichier ou de mémoire), il fera une nouvelle demande à /1.jpg?v=1
. Si entre-temps l'image a changé en /1.jpg?v=2
, la bonne réponse est soit:
- Servir l'ancienne version du fichier. Vous feriez cela si vous vouliez que toutes les ressources soient cohérentes les unes par rapport aux autres à un certain moment. C'est ce que vous devez faire avec les fichiers CSS, par exemple, car un nouveau fichier css avec un ancien fichier html peut ne pas fonctionner correctement!
- Redirigez vers la nouvelle version du fichier à l'aide de
301 Moved Permanently
. Vous feriez cela si vous vouliez que toutes les ressources soient aussi nouvelles que possible.
Les deux sont difficiles à faire avec un serveur Web seul, ce qui signifie que vous devez appeler une application Web même pour les demandes d'images, ce qui peut être à la fois plus compliqué et plus gourmand en ressources. Les serveurs Web sont très rapides à servir des fichiers, donc la surcharge d'une application Web peut finir par avaler vos gains de bande passante et de latence.
Noms de fichiers
Au lieu d'ajouter une chaîne de requête, vous modifiez le nom de fichier. Cela signifie qu'il est facile de conserver plusieurs versions de fichiers sur le système de fichiers, mais vous aurez probablement besoin de stocker les métadonnées de fichiers et de tenir d'autres registres de base de données pour garder une trace de vos ressources et de leurs noms.