Varnish Cache

Tussen je bezoeker en je website staan diverse caches die de snelheidservaring van je website drastisch kunnen verbeteren. Zo heb je de cache van een webbrowser, mogelijk een cache van je internet service provider en een server-side cache aan de kant van de webhosting provider. Al deze caches hebben als doel om bij herhaaldelijke pagina/website verzoeken (of "requests") de teruggave van het resultaat te versnellen.

Varnish

Op onze load-balancer draait een geavanceerd stuk software dat Varnish heet. Telkens als een pagina verzoek terug geleverd wordt aan de bezoeker kijkt Varnish of daarin een zogeheten Cache-Control header verwerkt zit, zo ja dan slaat het een kopie van de pagina in-memory op.

Varnish cache diagram

Nadat een pagina gecached is, ontvangen opvolgende bezoekers de gecachte versie zolang deze niet verlopen is. De Cache-Control header geeft daarbij ook aan hoe lang een pagina gecached mag worden.

In het artikel de snelheid van je website optimaliseren proberen we het nut van caching uit te leggen. Dit artikel gaat verder over de technische implementatie ervan.

Response headers

Bij iedere request worden er diverse headers mee teruggestuurd. Stel bijvoorbeeld dat je in een browser ons testdomein bezoekt, als reactie krijg je van onze webserver de volgende response headers terug:

HTTP/1.1 200 OK
Server: ONI-HA
Last-Modified: Wed, 24 Dec 2014 17:00:48 GMT
Cache-Control: max-age=3600
Vary: Accept-Encoding,User-Agent
Content-Encoding: gzip
Content-Type: text/html
Content-Length: 23
Accept-Ranges: bytes
Date: Wed, 24 Dec 2014 17:26:31 GMT
X-Varnish: 1224421005
Via: 1.1 varnish
Connection: keep-alive
X-Age: 0
X-Cache: MISS

Hier zitten een paar belangrijke headers tussen die te maken hebben met caching.

Cache-Control: deze header geeft aan hoe lang een request door tussenliggende caching servers mag worden opgeslagen. In feite wordt de datum aangegeven tot wanneer de teruggeven data geldig is. Zie ook Cache-Control MDN

X-Cache: deze header geeft aan of een request al dan niet uit onze server-side cache is gekomen. Bij HIT is dat het geval, bij MISS komt het antwoord van een webserver. In het bovenstaande geval was de request dus niet door de caching-server afgehandeld maar doorgestuurd naar de webserver. Als je deze direct nog een keer opvraagt zal de header HIT weergeven. Dit is precies waar het bij caching om gaat, het teruggeven van in-memory opgeslagen data uit onze caching server zal altijd beduidend sneller zijn dan vanaf een webserver.

De Cache-Control header is door jou zelf te bepalen, maar hoe hangt af van het type request, statisch (onveranderlijke data) of dynamisch (variabele data).

Statische requests

Statische bestanden zoals html, javascript, css en plaatjes worden door een webserver in zijn geheel teruggegeven, om deze van een Expires header te voorzien kan je dit in een .htaccess bestand als volgt aangeven:

<IfModule mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 days"
</IfModule>

Hiermee zet je de standaard expiratie van de cache van alle statische bestanden op één dag. Uiteraard kan dit ook 8 uur, 2 minuten, nooit, of 10 jaar zijn, bestudeer deze pagina voor alle mogelijke opties.

Dynamische requests

Bij een dynamisch request kan de data die teruggegeven wordt variabel zijn, bijvoorbeeld omdat deze door een php script wordt gegenereerd. Stel bijvoorbeeld dat je een blog artikel hebt geschreven, deze staat dan in een database en een php script voegt deze content samen met wat templates en geeft dit als html terug aan de bezoeker. Dit blog artikel zal waarschijnlijk niet iedere minuut veranderen en omdat het uitvoeren van een dynamisch request zwaarder is dan het ophalen van een statisch request, zou je juist ook bij dit type request veel baat hebben om deze te cachen.

Dit kan door de Expires header terug te geven met de header() functie van PHP:

<php header('Cache-Control: max-age=86400'); ?>

De exacte implementatie hiervan is per website specifiek. Voor Wordpress zijn er bijvoorbeeld diverse plugins die je hiervoor zou kunnen gebruiken.

Cache omzeilen

Soms kan je last hebben van je eigen cache regels omdat je even wat wilt updaten en dan niet een uur wilt wachten totdat de oude versie van een request uit onze server-side cache verlopen is. Gelukkig is er een makkelijke truc om in je browser een "hard refresh" te forceren.

Op Windows/Linux:

Ctrl+F5 of Ctrl+Shift+R

Apple:

⌘Cmd+R

Pro-tip: als je bij het developen Chrome DevTools gebruikt, schakel dan de "Disable cache (while DevTools is open)" optie in.

Chrome developer tools cache uitschakelen