HTTP Caching
Binnen HTTP worden twee cachingmechanismen voorzien, die gelijktijdig of elk afzonderlijk kunnen worden geïmplementeerd. Ik overloop ze even. De nuances laat ik achterwege en ik geef ook geen garantie op de acuratesse (er zit al wat roest op mijn technische skills), beschouw het onderstaande dus als “the bigger picture”.
De eerste vorm van caching is tijdgebaseerd. Hiervoor wordt de verouderde Expires-header en de nieuwe Cache-Control max-age response header gebruikt. Binnen de gespecifieerde periode wordt de cache als “fresh” beschouwd en is het niet nodig de server opnieuw te contacteren. Indien de response te oud is, en de cache dus “stale” is, zal de client de server contacteren, maar niet zoals je zou verwachten: de client zal niet zomaar zijn cache weggooien maar een cacherevalidatie-proces starten. De client voert zijn request uit om de resource opnieuw op te vragen, maar voegt een If-Modified-Since header toe aan zijn request. Indien de resource niet werd gewijzigd, zal de server antwoorden met een 304-statuscode (“Not modified”), met een nieuwe Cache-Control max-age response header, en met de response body achterwege gelaten. Met andere woorden: de client krijgt de instructie om de de cached response uit het verleden terug als fresh te beschouwen voor een zekere tijd. Het voordeel van deze tijdgebaseerde vorm van caching is dat effectief round trips worden vermeden: de client stuurt geen request indien de response uit het verleden, op basis van tijd, nog “nieuw genoeg” is. Het nadeel is dat deze vorm van caching heel sterk afhangt van vooraf gekende en doorheen de ketting noodzakelijk correct gesynchroniseerde tijdstempels. Eén fout kan drastische gevolgen hebben voor de correcte werking van veel recurring visitors van de webapplicatie. De beheerder staat hierbij machteloos en kan enkel toekijken van de zijlijn.
Dat brengt ons bij de tweede vorm van caching: inhoudgebaseerde caching. De server stuurt in zijn response een ETag-header mee, zijnde een hash van de response body. De client cached de resource, en bij een volgende request van de client, zal deze een If-None-Match header meesturen met daarin de ETag van de eerder ontvangen response. Indien de resource niet werd gewijzigd, zal de server de intussen gekende 304-statuscode (“Not modified”) terugsturen en de response body achterwege laten. Het voordeel van deze inhoudgebaseerde vorm van caching is dat deze “altijd werkt”. De client zal altijd, indien nodig, de nieuwste versie ontvangen. Anderzijds zal de client wel altijd een request moeten versturen. Er worden dus geen requests uitgespaard, enkel de response bodies worden mogelijk achterwege gelaten.
Om te kunnen genieten van de voordelen van tijdgebaseerde caching (het vermijden van de request), zonder de risico’s te lopen (foutief ingestelde caching met mogelijk dramatische gevolgen voor de recurring visitors), gebruiken veel web developers een techniek genaamd “cache busting”. Meestal gaat dit als volgt: de bundler voegt aan alle bestanden behalve index.html in de bestandsnaam een hash toe van de inhoud. In plaats van style.css krijgen we dus style-