[Medium] đ HTTP Caching
1. What is HTTP caching and why is it important?â
Qu'est-ce que le cache HTTP ? Pourquoi est-il important ?
Le cache HTTP est une technique qui stocke temporairement les rĂ©ponses HTTP cĂŽtĂ© client (navigateur) ou sur des serveurs intermĂ©diaires, afin de pouvoir utiliser directement les donnĂ©es mises en cache lors des requĂȘtes suivantes, sans avoir Ă les redemander au serveur.
Cache vs stockage temporaire : quelle est la diffĂ©rence ?â
Dans la documentation technique, ces deux termes sont souvent utilisés de maniÚre interchangeable, mais ils ont en réalité des significations différentes :
Cacheâ
Définition : Copies de données stockées pour l'optimisation des performances, mettant l'accent sur la "réutilisation" et l'"accÚs plus rapide".
Caractéristiques :
- â L'objectif est d'amĂ©liorer les performances
- â Les donnĂ©es peuvent ĂȘtre rĂ©utilisĂ©es
- â Politiques d'expiration clairement dĂ©finies
- â GĂ©nĂ©ralement des copies des donnĂ©es originales
Exemple :
// HTTP Cache - Mettre en cache les réponses d'API
Cache-Control: max-age=3600 // Cache pendant 1 heure
// Memory Cache - Mettre en cache les résultats de calcul
const cache = new Map();
function fibonacci(n) {
if (cache.has(n)) return cache.get(n); // Réutiliser le cache
const result = /* calcul */;
cache.set(n, result);
return result;
}
Temporary Storage (Stockage temporaire)â
Définition : Données stockées temporairement, mettant l'accent sur la "temporalité" et "seront supprimées".
Caractéristiques :
- â L'objectif est le stockage temporaire
- â Pas nĂ©cessairement rĂ©utilisĂ©
- â Cycle de vie gĂ©nĂ©ralement court
- â Peut contenir des Ă©tats intermĂ©diaires
Exemple :
// sessionStorage - Stocker temporairement les entrées utilisateur
sessionStorage.setItem('formData', JSON.stringify(form)); // Supprimé à la fermeture de l'onglet
// Stockage temporaire des fichiers téléchargés
const tempFile = await uploadToTemp(file); // Supprimer aprĂšs traitement
await processFile(tempFile);
await deleteTempFile(tempFile);
Tableau comparatifâ
| Caractéristique | Cache | Temporary Storage (Stockage temporaire) |
|---|---|---|
| Objectif principal | Optimisation des performances | Stockage temporaire |
| Réutilisation | Oui, lectures multiples | Pas nécessairement |
| Cycle de vie | Basé sur la politique | Généralement court |
| Usage typique | HTTP Cache, Memory Cache | sessionStorage, fichiers temporaires |
| Ăquivalent anglais | Cache | Temp / Temporary / Buffer |
DiffĂ©rences dans l'application pratiqueâ
// ===== Scénarios d'utilisation du Cache =====
// 1. HTTP Cache : Réutiliser les réponses d'API
fetch('/api/users') // PremiĂšre requĂȘte
.then((response) => response.json());
fetch('/api/users') // DeuxiĂšme lecture depuis le cache
.then((response) => response.json());
// 2. Cache des résultats de calcul
const memoize = (fn) => {
const cache = new Map();
return (...args) => {
const key = JSON.stringify(args);
if (cache.has(key)) return cache.get(key); // Réutiliser
const result = fn(...args);
cache.set(key, result);
return result;
};
};
// ===== Scénarios d'utilisation du Stockage temporaire =====
// 1. Stockage temporaire des données de formulaire (prévenir la fermeture accidentelle)
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('formDraft', JSON.stringify(formData));
});
// 2. Stockage temporaire des fichiers téléchargés
async function handleUpload(file) {
const tempPath = await uploadToTempStorage(file); // Stockage temporaire
const processed = await processFile(tempPath);
await deleteTempFile(tempPath); // Supprimer aprĂšs utilisation
return processed;
}
// 3. Stockage temporaire des résultats intermédiaires
const tempResults = []; // Stocker les résultats intermédiaires
for (const item of items) {
tempResults.push(process(item));
}
const final = combine(tempResults); // Plus nécessaire aprÚs utilisation
Application dans le dĂ©veloppement webâ
// HTTP Cache - Stockage à long terme, réutilisation
Cache-Control: public, max-age=31536000, immutable
// â Le navigateur mettra ce fichier en cache pendant un an et le rĂ©utilisera
// sessionStorage (Stockage temporaire) - Stockage temporaire, supprimé à la fermeture
sessionStorage.setItem('tempData', data);
// â Valide uniquement dans l'onglet actuel, supprimĂ© Ă la fermeture
// localStorage (Stockage Ă long terme) - Entre les deux
localStorage.setItem('userPreferences', prefs);
// â Stockage persistant, mais pas pour l'optimisation des performances
Pourquoi est-il important de distinguer ces deux concepts ?â
-
Décisions de conception :
- Besoin d'optimisation des performances ? â Utiliser le cache
- Besoin de stockage temporaire ? â Utiliser le stockage temporaire
-
Gestion des ressources :
- Cache : Focus sur le taux de réussite et les politiques d'expiration
- Stockage temporaire : Focus sur le moment du nettoyage et les limites de capacité
-
Réponses en entretien :
- "Comment optimiser les performances" â Parler des stratĂ©gies de cache
- "Comment gĂ©rer les donnĂ©es temporaires" â Parler des solutions de stockage temporaire
Dans cet article, nous discutons principalement du Cache, en particulier du mécanisme de cache HTTP.
Avantages du cacheâ
- RĂ©duction des requĂȘtes rĂ©seau : Lire directement depuis le cache local, sans envoyer de requĂȘtes HTTP
- RĂ©duction de la charge serveur : Moins de requĂȘtes Ă traiter par le serveur
- Vitesse de chargement des pages plus rapide : La lecture du cache local est beaucoup plus rapide que les requĂȘtes rĂ©seau
- Ăconomie de bande passante : RĂ©duction du volume de transfert de donnĂ©es
- Amélioration de l'expérience utilisateur : Réponses de page plus rapides, utilisation plus fluide
Types de cacheâ
âââââââââââââââââââââââââââââââââââââââ
â HiĂ©rarchie du cache navigateur â
âââââââââââââââââââââââââââââââââââââââ€
â 1. Memory Cache (Cache mĂ©moire) â
â - Le plus rapide, petite â
â capacitĂ© â
â - SupprimĂ© Ă la fermeture â
â de l'onglet â
âââââââââââââââââââââââââââââââââââââââ€
â 2. Disk Cache (Cache disque) â
â - Plus lent, grande capacitĂ© â
â - Stockage persistant â
âââââââââââââââââââââââââââââââââââââââ€
â 3. Service Worker Cache â
â - ContrĂŽle total du â
â dĂ©veloppeur â
â - Support des applications â
â hors ligne â
âââââââââââââââââââââââââââââââââââââââ
2. What are the HTTP caching strategies?â
Quelles sont les stratégies de cache HTTP ?
Classification des stratĂ©gies de cacheâ
Stratégies de cache HTTP
âââ Cache fort (Strong Cache)
â âââ Cache-Control
â âââ Expires
âââ Cache de nĂ©gociation (Negotiation Cache)
âââ Last-Modified / If-Modified-Since
âââ ETag / If-None-Match
1. Cache fort (Strong Cache / Fresh)â
CaractĂ©ristique : Le navigateur lit directement depuis le cache local sans envoyer de requĂȘte au serveur.
Cache-Control (HTTP/1.1)â
Cache-Control: max-age=3600
Directives courantes :
// 1. max-age : Durée de validité du cache (secondes)
Cache-Control: max-age=3600 // Cache pendant 1 heure
// 2. no-cache : Validation auprÚs du serveur requise (cache de négociation)
Cache-Control: no-cache
// 3. no-store : Ne pas mettre en cache du tout
Cache-Control: no-store
// 4. public : Peut ĂȘtre mis en cache par n'importe quel cache (navigateur, CDN)
Cache-Control: public, max-age=31536000
// 5. private : Seul le navigateur peut mettre en cache
Cache-Control: private, max-age=3600
// 6. immutable : La ressource ne change jamais (avec nom de fichier hash)
Cache-Control: public, max-age=31536000, immutable
// 7. must-revalidate : AprĂšs expiration, validation auprĂšs du serveur obligatoire
Cache-Control: max-age=3600, must-revalidate
Expires (HTTP/1.0, obsolĂšte)â
Expires: Wed, 21 Oct 2025 07:28:00 GMT
ProblĂšmes :
- Utilise un temps absolu, dépend de l'heure du client
- Une heure client inexacte entraĂźne un dysfonctionnement du cache
- Remplacé par
Cache-Control
2. Cache de nĂ©gociation (Negotiation Cache / Validation)â
CaractĂ©ristique : Le navigateur envoie une requĂȘte au serveur pour vĂ©rifier si la ressource a Ă©tĂ© mise Ă jour.
Last-Modified / If-Modified-Sinceâ
# RĂ©ponse du serveur (premiĂšre requĂȘte)
Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT
# RequĂȘte du navigateur (requĂȘtes suivantes)
If-Modified-Since: Wed, 21 Oct 2024 07:28:00 GMT
Processus :
- PremiĂšre requĂȘte : Le serveur renvoie
Last-Modified - RequĂȘtes suivantes : Le navigateur inclut
If-Modified-Since - Ressource non modifiée : Le serveur renvoie
304 Not Modified - Ressource modifiée : Le serveur renvoie
200 OKet la nouvelle ressource
ETag / If-None-Matchâ
# RĂ©ponse du serveur (premiĂšre requĂȘte)
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
# RequĂȘte du navigateur (requĂȘtes suivantes)
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Avantages :
- Plus précis que
Last-Modified - Ne dépend pas du temps, utilise le hash du contenu
- Peut détecter les changements en dessous de la seconde
Last-Modified vs ETagâ
| Caractéristique | Last-Modified | ETag |
|---|---|---|
| Précision | Niveau seconde | Hash du contenu, plus précis |
| Performance | Plus rapide | Calcul de hash nécessaire, plus lent |
| Cas d'utilisation | Ressources statiques générales | Ressources nécessitant un contrÎle précis |
| Priorité | Basse | Haute (ETag prioritaire) |
3. How does browser caching work?â
Comment fonctionne le cache du navigateur ?
Flux de cache completâ
ââââââââââââââââââââââââââââââââââââââââââââââââ
â Flux de requĂȘte de ressources du â
â navigateur â
ââââââââââââââââââââââââââââââââââââââââââââââââ
â
1. Vérifier Memory Cache
â
âââââââââŽâââââââââ
â Cache trouvĂ© ? â
âââââââââŹâââââââââ
Yes â No
â
2. Vérifier Disk Cache
â
âââââââââŽâââââââââ
â Cache trouvĂ© ? â
âââââââââŹâââââââââ
Yes â No
â
3. Vérifier Service Worker
â
âââââââââŽâââââââââ
â Cache trouvĂ© ? â
âââââââââŹâââââââââ
Yes â No
â
4. Vérifier l'expiration du cache
â
âââââââââŽâââââââââ
â ExpirĂ© ? â
âââââââââŹâââââââââ
Yes â No
â
5. Valider avec le cache de négociation
â
âââââââââŽâââââââââ
â Ressource â
â modifiĂ©e ? â
âââââââââŹâââââââââ
Yes â No (304)
â
6. Demander une nouvelle ressource au serveur
â
âââââââââŽâââââââââ
â Renvoyer â
â nouvelle â
â ressource â
â (200 OK) â
ââââââââââââââââââ
Exemple pratiqueâ
// PremiĂšre requĂȘte
GET /api/data.json
Response:
200 OK
Cache-Control: max-age=3600
ETag: "abc123"
{ data: "..." }
// ========== Nouvelle requĂȘte dans l'heure ==========
// Cache fort : Lire directement depuis le local, sans envoyer de requĂȘte
// Status: 200 OK (from disk cache)
// ========== Nouvelle requĂȘte aprĂšs 1 heure ==========
// Cache de nĂ©gociation : Envoyer une requĂȘte de validation
GET /api/data.json
If-None-Match: "abc123"
// Ressource non modifiée
Response:
304 Not Modified
(Pas de body, utiliser le cache local)
// Ressource modifiée
Response:
200 OK
ETag: "def456"
{ data: "new data" }
4. What are the common caching strategies?â
Quelles sont les stratégies de cache les plus courantes ?
1. StratĂ©gie de cache permanent (pour les ressources statiques)â
// HTML : Ne pas mettre en cache, vérifier à chaque fois
Cache-Control: no-cache
// CSS/JS (avec hash) : Cache permanent
Cache-Control: public, max-age=31536000, immutable
// Nom de fichier : main.abc123.js
Principe :
- Le HTML n'est pas mis en cache, garantissant que l'utilisateur obtient la derniĂšre version
- CSS/JS utilisent des noms de fichiers avec hash, le nom change quand le contenu change
- Les anciennes versions ne sont pas utilisées, les nouvelles sont retéléchargées
2. StratĂ©gie pour les ressources frĂ©quemment mises Ă jourâ
// Données d'API : Cache de courte durée + cache de négociation
Cache-Control: max-age=60, must-revalidate
ETag: "abc123"
3. StratĂ©gie pour les ressources d'imagesâ
// Avatar utilisateur : Cache Ă moyen terme
Cache-Control: public, max-age=86400 // 1 jour
// Logo, icĂŽnes : Cache Ă long terme
Cache-Control: public, max-age=2592000 // 30 jours
// Images dynamiques : Cache de négociation
Cache-Control: no-cache
ETag: "image-hash"
4. Recommandations de cache par type de ressourceâ
const cachingStrategies = {
// Fichiers HTML
html: 'Cache-Control: no-cache',
// Ressources statiques avec hash
staticWithHash: 'Cache-Control: public, max-age=31536000, immutable',
// Ressources statiques rarement mises Ă jour
staticAssets: 'Cache-Control: public, max-age=2592000',
// Données d'API
apiData: 'Cache-Control: private, max-age=60',
// Données spécifiques à l'utilisateur
userData: 'Cache-Control: private, no-cache',
// Données sensibles
sensitive: 'Cache-Control: no-store',
};
5. Service Worker cachingâ
Cache Service Worker
Le Service Worker offre le contrÎle de cache le plus flexible, permettant aux développeurs de contrÎler entiÚrement la logique de cache.
Utilisation de baseâ
// Enregistrer le Service Worker
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js');
}
// sw.js - Fichier Service Worker
const CACHE_NAME = 'my-app-v1';
const urlsToCache = [
'/',
'/styles/main.css',
'/scripts/main.js',
'/images/logo.png',
];
// ĂvĂ©nement d'installation : Mettre en cache les ressources statiques
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll(urlsToCache);
})
);
});
// Interception des requĂȘtes : Utiliser la stratĂ©gie de cache
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
// Stratégie Cache First
return response || fetch(event.request);
})
);
});
// ĂvĂ©nement d'activation : Nettoyer l'ancien cache
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
if (cacheName !== CACHE_NAME) {
return caches.delete(cacheName);
}
})
);
})
);
});
StratĂ©gies de cache courantesâ
1. Cache First (Cache en premier)â
// Adapté pour : Ressources statiques
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((response) => {
return response || fetch(event.request);
})
);
});
2. Network First (RĂ©seau en premier)â
// AdaptĂ© pour : RequĂȘtes d'API
self.addEventListener('fetch', (event) => {
event.respondWith(
fetch(event.request)
.then((response) => {
// Mettre Ă jour le cache
const responseClone = response.clone();
caches.open(CACHE_NAME).then((cache) => {
cache.put(event.request, responseClone);
});
return response;
})
.catch(() => {
// Réseau échoué, utiliser le cache
return caches.match(event.request);
})
);
});
3. Stale While Revalidate (ObsolĂšte pendant la revalidation)â
// Adapté pour : Ressources nécessitant des réponses rapides tout en restant à jour
self.addEventListener('fetch', (event) => {
event.respondWith(
caches.match(event.request).then((cachedResponse) => {
const fetchPromise = fetch(event.request).then((networkResponse) => {
caches.open(CACHE_NAME).then((cache) => {
cache.put(event.request, networkResponse.clone());
});
return networkResponse;
});
// Renvoyer le cache, mettre Ă jour en arriĂšre-plan
return cachedResponse || fetchPromise;
})
);
});
6. How to implement cache busting?â
Comment implémenter le Cache Busting ?
Le Cache Busting est une technique qui garantit que les utilisateurs obtiennent les ressources les plus récentes.
MĂ©thode 1 : Hash dans le nom de fichier (recommandĂ©e)â
// Utiliser des outils de bundling comme Webpack/Vite
// Sortie : main.abc123.js
// webpack.config.js
module.exports = {
output: {
filename: '[name].[contenthash].js',
},
};
<!-- Mettre à jour automatiquement la référence -->
<script src="/js/main.abc123.js"></script>
Avantages :
- â Le nom de fichier change, forçant le tĂ©lĂ©chargement du nouveau fichier
- â L'ancienne version reste en cache, pas de gaspillage
- â Meilleure pratique
MĂ©thode 2 : NumĂ©ro de version dans le Query Stringâ
<!-- Mettre à jour manuellement le numéro de version -->
<script src="/js/main.js?v=1.2.3"></script>
<link rel="stylesheet" href="/css/style.css?v=1.2.3" />
Inconvénients :
- â Certains CDN ne mettent pas en cache les ressources avec un query string
- â Maintenance manuelle du numĂ©ro de version nĂ©cessaire
MĂ©thode 3 : Horodatageâ
// Utiliser en environnement de développement
const timestamp = Date.now();
const script = document.createElement('script');
script.src = `/js/main.js?t=${timestamp}`;
document.body.appendChild(script);
Usage :
- Ăviter le cache en environnement de dĂ©veloppement
- InadaptĂ© Ă l'environnement de production (chaque fois une nouvelle requĂȘte)
7. Common caching interview questionsâ
Questions d'entretien courantes sur le cache
Question 1 : Comment empĂȘcher le HTML d'ĂȘtre mis en cache ?â
Cliquez pour voir la réponse
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Ou utiliser des balises meta :
<meta
http-equiv="Cache-Control"
content="no-cache, no-store, must-revalidate"
/>
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
Question 2 : Pourquoi utiliser ETag plutĂŽt que seulement Last-Modified ?â
Cliquez pour voir la réponse
Avantages de l'ETag :
- Plus précis : Peut détecter les changements en dessous de la seconde
- Basé sur le contenu : Basé sur le hash du contenu, pas sur le temps
- Ăviter les problĂšmes de temps :
- Le contenu du fichier n'a pas changé mais l'heure a changé (comme lors d'un redéploiement)
- Ressources mises Ă jour cycliquement (retour pĂ©riodique au mĂȘme contenu)
- SystĂšmes distribuĂ©s : Les horloges de diffĂ©rents serveurs peuvent ne pas ĂȘtre synchronisĂ©es
Exemple :
// Le contenu du fichier n'a pas changé, mais Last-Modified a changé
// 2024-01-01 12:00 - Déployer version A (contenu : abc)
// 2024-01-02 12:00 - Redéployer version A (contenu : abc)
// Last-Modified a changĂ©, mais le contenu est le mĂȘme !
// ETag n'a pas ce problĂšme
ETag: 'hash-of-abc'; // Toujours identique
Question 3 : Quelle est la diffĂ©rence entre from disk cache et from memory cache ?â
Cliquez pour voir la réponse
| Caractéristique | Memory Cache | Disk Cache |
|---|---|---|
| Emplacement | Mémoire (RAM) | Disque dur |
| Vitesse | ExtrĂȘmement rapide | Plus lent |
| Capacité | Petite (niveau Mo) | Grande (niveau Go) |
| Persistance | Supprimé à la fermeture de l'onglet | Stockage persistant |
| Priorité | Haute (prioritaire) | Basse |
Ordre de priorité de chargement :
1. Memory Cache (le plus rapide)
2. Service Worker Cache
3. Disk Cache
4. HTTP Cache
5. RequĂȘte rĂ©seau (le plus lent)
Conditions de déclenchement :
- Memory Cache : Ressources récemment accédées (comme le rechargement de la page)
- Disk Cache : Ressources accédées il y a longtemps ou fichiers volumineux
Question 4 : Comment forcer le navigateur Ă recharger les ressources ?â
Cliquez pour voir la réponse
Phase de développement :
// 1. Hard Reload (Ctrl/Cmd + Shift + R)
// 2. Vider le cache et recharger
// 3. Ajouter un horodatage dans le code
const script = document.createElement('script');
script.src = `/js/main.js?t=${Date.now()}`;
Environnement de production :
// 1. Utiliser le hash dans le nom de fichier (meilleure pratique)
main.abc123.js // Généré automatiquement par Webpack/Vite
// 2. Mettre à jour le numéro de version
<script src="/js/main.js?v=2.0.0"></script>
// 3. Configurer Cache-Control
Cache-Control: no-cache // Forcer la validation
Cache-Control: no-store // Ne pas mettre en cache du tout
Question 5 : Comment implĂ©menter le cache hors ligne PWA ?â
Cliquez pour voir la réponse
// sw.js - Service Worker
const CACHE_NAME = 'pwa-v1';
const OFFLINE_URL = '/offline.html';
// Mettre en cache la page hors ligne lors de l'installation
self.addEventListener('install', (event) => {
event.waitUntil(
caches.open(CACHE_NAME).then((cache) => {
return cache.addAll([
OFFLINE_URL,
'/styles/offline.css',
'/images/offline-icon.png',
]);
})
);
});
// Interception des requĂȘtes
self.addEventListener('fetch', (event) => {
if (event.request.mode === 'navigate') {
event.respondWith(
fetch(event.request).catch(() => {
// Réseau échoué, afficher la page hors ligne
return caches.match(OFFLINE_URL);
})
);
}
});
Stratégie de cache PWA complÚte :
// 1. Mettre en cache les ressources statiques
caches.addAll(['/css/', '/js/', '/images/']);
// 2. RequĂȘtes d'API : Network First
// 3. Images : Cache First
// 4. HTML : Network First, afficher la page hors ligne en cas d'échec
8. Best practicesâ
Bonnes pratiques
â Pratiques recommandĂ©esâ
// 1. HTML - Ne pas mettre en cache, garantir que l'utilisateur obtient la derniĂšre version
// Response Headers:
Cache-Control: no-cache
// 2. CSS/JS (avec hash) - Cache permanent
// Nom de fichier : main.abc123.js
Cache-Control: public, max-age=31536000, immutable
// 3. Images - Cache Ă long terme
Cache-Control: public, max-age=2592000 // 30 jours
// 4. Données d'API - Cache à court terme + cache de négociation
Cache-Control: private, max-age=60
ETag: "api-response-hash"
// 5. Utiliser le Service Worker pour le support hors ligne
â Pratiques Ă Ă©viterâ
// â Mauvais : Configurer un cache Ă long terme pour le HTML
Cache-Control: max-age=31536000 // L'utilisateur pourrait voir une ancienne version
// â Mauvais : Utiliser Expires au lieu de Cache-Control
Expires: Wed, 21 Oct 2025 07:28:00 GMT // HTTP/1.0, obsolĂšte
// â Mauvais : Ne configurer aucun cache
// Sans en-tĂȘtes de cache, le comportement du navigateur est indĂ©terminĂ©
// â Mauvais : Utiliser la mĂȘme stratĂ©gie pour toutes les ressources
Cache-Control: max-age=3600 // Devrait ĂȘtre ajustĂ© selon le type de ressource
Arbre de dĂ©cision de la stratĂ©gie de cacheâ
Ressource statique ?
ââ Oui â Le nom de fichier a un hash ?
â ââ Oui â Cache permanent (max-age=31536000, immutable)
â ââ Non â Cache Ă moyen-long terme (max-age=2592000)
ââ Non â Est-ce du HTML ?
ââ Oui â Ne pas mettre en cache (no-cache)
ââ Non â Est-ce une API ?
ââ Oui â Cache Ă court terme + nĂ©gociation (max-age=60, ETag)
ââ Non â DĂ©cider selon la frĂ©quence de mise Ă jour