Cache-Control: minder verzoeken, snellere pagina’s

Telkens wanneer een browser uw pagina laadt, heeft hij uw afbeeldingen, stylesheets en scripts nodig. Zegt u niets, dan beslist de browser zelf hoe lang hij elk bestand vertrouwt en checkt hij geregeld opnieuw bij de server — wat een stroom „304 Not Modified”-antwoorden in uw logbestanden oplevert. Elke hervalidatie is een extra rondje naar de server waar uw bezoeker op wacht en werk dat uw server verzet, zelfs als er niets veranderd is. Cache-Control lost dat op door browsers te vertellen hoe lang ze een bestand mogen hergebruiken zonder het opnieuw te vragen.

Hoe caching werkt

Wanneer een browser een bestand opvraagt dat nog niet in zijn cache zit, downloadt hij het. Bij latere bezoeken, zonder cachingregels, stuurt hij vaak een voorwaardelijk verzoek: „is dit veranderd?” Bevat het antwoord een bruikbare validator — een ETag- of Last-Modified-header — dan kan de server „304 Not Modified” antwoorden: geen nieuwe gegevens, maar wél nog een rondje naar de server. (Zonder validator moet het hele bestand opnieuw verstuurd worden.) Met Cache-Control slaat u dat rondje volledig over voor bestanden die het niet nodig hebben:

Cache-Control: public, max-age=604800

max-age staat in seconden (604800 = 7 dagen). Zolang de kopie in de cache vers is en er nog in zit, hergebruikt de browser ze normaal gesproken zonder de server ook maar te contacteren. Cache-Control heeft de oudere Expires-header grotendeels vervangen, al werken beide nog.

no-cache, no-store en private — drie verschillende zaken

Deze drie directieven haalt men gemakkelijk door elkaar, en de namen zijn misleidend:

  • no-cache betekent niet „niet cachen”. Het betekent dat een cache het antwoord mag opslaan, maar het opnieuw moet valideren bij de server voordat hij het hergebruikt — een instructie in de trant van „check eerst bij mij voordat u uw kopie vertrouwt”. Een nuttige standaard voor HTML die vóór hergebruik gecontroleerd moet worden; combineer ze met een validator, zodat het antwoord een goedkope 304 kan zijn. (Stabiele, openbare HTML kan in plaats daarvan een korte geldigheidsduur krijgen.)
  • no-store zegt conforme HTTP-caches het antwoord helemaal niet te bewaren voor later hergebruik. Gebruik het voor echt gevoelige antwoorden (een pagina met bankgegevens) — naast degelijke toegangscontrole, want het houdt geen schermafbeeldingen, downloads of een niet-conforme tussenschakel die toch een kopie bijhoudt tegen.
  • private betekent dat conforme gedeelde caches — een CDN, een proxy — het antwoord niet mogen opslaan; alleen de browser van de bezoeker zelf mag dat. Gebruik het voor gepersonaliseerde inhoud, zoals een dashboard achter een login. De applicatie moet nog steeds toegangscontrole afdwingen en cache-items per gebruiker gescheiden houden: private kan een edge-regel die het verkeerde in de cache zet, niet rechtzetten.

Voor de meeste statische bestanden wilt u het omgekeerde: public met een lange max-age — waar public veilig is, dat wil zeggen: het antwoord is voor elke bezoeker identiek.

Aanbevolen instellingen

  • Statische bestanden waarvan de URL mee verandert met de inhoud (geversioneerde CSS, JS, afbeeldingen, lettertypen): cache ze agressief.
  • Bestanden op herbruikbare URL’s zonder versie: een levensduur kort genoeg voor de veroudering die u kunt verdragen.
  • HTML: opnieuw valideren of kort cachen; strenger (private, no-store) waar gepersonaliseerd of gevoelig.

Op Apache stelt u de headers in met mod_headers in .htaccess (waar uw host die directieven toestaat — mod_expires is een aparte, nog steeds actuele module die in plaats daarvan vervaltijden beheert):

<IfModule mod_headers.c>
  # Use only when every matching URL is versioned — the regex can't check that for you
  <FilesMatch "\.(webp|avif|png|jpg|jpeg|gif|svg|woff2|css|js)$">
    Header set Cache-Control "public, max-age=31536000, immutable"
  </FilesMatch>
  # HTML — always revalidate
  <FilesMatch "\.(html|php)$">
    Header set Cache-Control "no-cache"
  </FilesMatch>
</IfModule>

Belangrijk: de eenjarige immutable-regel is alleen veilig voor bestandsnamen met een vingerafdruk of versie (style.a1b2c3.css, app.9f2.js). Deze FilesMatch vangt elk bestand met die extensies, dus als uw CSS, JS of afbeeldingen gewone namen zonder versie dragen (style.css, logo.png), blijven verouderde kopieën een jaar lang vastzitten in de browsers van uw bezoekers — „we wijzigen het zelden” is niet genoeg voor immutable. Geef uw bestandsnamen dus eerst een versie (zie hieronder), of geef assets zonder versie een veel kortere max-age en laat immutable weg. En controleer na het instellen welke headers een bezoeker daadwerkelijk ontvangt op de openbare URL: een reverse proxy of CDN die ervoor staat, kan het cachebeleid van uw eigen server herschrijven of negeren.

Het probleem van „verouderde bestanden” oplossen met versiebeheer

Lange cache-levensduur brengt één zorg met zich mee: hoe krijgen bezoekers uw update te zien als hun browser de opdracht heeft gekregen het oude bestand een jaar lang te bewaren? Het antwoord is cache busting — wijzig de bestandsnaam wanneer de inhoud verandert:

style.css        →  style.a1b2c3.css

Omdat de URL nieuw is, halen browsers het bestand vers op, terwijl alle ongewijzigde bestanden in de cache blijven staan. Er zijn twee voorwaarden om dit te laten werken: werk elke verwijzing (HTML, CSS, preloads, manifest) bij naar de nieuwe URL, en laat het oude bestand online staan totdat de gecachete HTML die er nog naar verwijst, verlopen is — het cachebeleid van de HTML zelf maakt deel uit van het systeem. Veel productie-buildpijplijnen genereren deze inhoudshashes wanneer u ze daarvoor instelt.

Geef browsers aan wat zij veilig kunnen hergebruiken; hierdoor worden herhaalde bezoeken sneller en worden er minder verzoeken naar uw server gestuurd.

Wat u moet doen

  1. Stel een lange max-age (met immutable) in op statische assets — maar alleen zodra hun bestandsnamen een versie dragen; geef bestanden zonder versie in plaats daarvan een korte levensduur.
  2. Houd HTML op no-cache met een werkende ETag/Last-Modified, of een korte levensduur; gebruik private voor gepersonaliseerde pagina’s en no-store (plus toegangscontrole) voor echt gevoelige pagina’s.
  3. Geef bestandsnamen van assets een versie en werk elke verwijzing bij wanneer de inhoud verandert.
  4. Schakel ook Gzip/Brotli-compressie in en controleer de headers die daadwerkelijk aankomen op de openbare URL — een CDN kan ze onderweg wijzigen.
  5. Kijk daarna opnieuw in uw logbestanden: herhaalde verzoeken en 304’s voor langlevende assets met versie zouden moeten afnemen (HTML op no-cache blijft per ontwerp hervalideren).

Veelgestelde vragen

Hoe kan ik voorkomen dat bezoekers door lange cache-tijden een verouderd bestand te zien krijgen?
Gebruik cache busting: geef het bestand een nieuwe URL telkens wanneer de inhoud verandert, bijvoorbeeld van style.css naar style.a1b2c3.css, en werk elke verwijzing ernaar bij. Browsers behandelen de onbekende URL als een verse download, terwijl ongewijzigde bestanden in de cache blijven. Veel productie-buildpijplijnen kunnen deze inhoudshashes genereren wanneer u ze daarvoor instelt — en houd het oude bestand online totdat de gecachete HTML die ernaar verwijst, verlopen is.
Welke `max-age`-waarde moet ik instellen voor afbeeldingen, CSS en JavaScript?
Assets waarvan de URL mee verandert met de inhoud — afbeeldingen, lettertypen, CSS én JavaScript — kunnen een lange `max-age` (zeg 31536000) met `immutable` krijgen. Geef herbruikbare URL’s zonder versie een levensduur die kort genoeg is voor de veroudering die u kunt verdragen. Houd HTML die actueel moet blijven op `no-cache` of een korte levensduur, en gebruik `private` of `no-store` waar personalisatie of gevoeligheid dat vraagt.

Op zoek naar meer? Bekijk alle websitetips.

Bron: “Cache-Control: minder verzoeken, snellere pagina’s” — https://www.siteadvice.be/nl/articles/cache-control/ · © 2026 EUREGIO.NET AG. Alle rechten voorbehouden.