Verlaag de cache duration van de Time to First Byte

De cache duration meet de lookuptijd van de service worker en de browser cache. Leer caching-strategieën, Cache-Control-headers, bfcache en service worker-optimalisatie om de TTFB te verlagen.

  • Goed ≤ 0,8 s
  • Verbetering nodig ≤ 1,8 s
  • Slecht > 1,8 s
Arjen Karel
Bijgewerkt · 7 min lezen
Delen

Verlaag de cache duration van de Time to First Byte

Dit artikel is onderdeel van onze Time to First Byte (TTFB)-handleiding. De cache duration is het tweede subonderdeel van de TTFB en staat voor de tijd die de browser kwijt is aan het controleren van de lokale cache en actieve service workers op een matchende response. De cache duration is zelden het primaire knelpunt, maar inzicht hierin is belangrijk voor sites die service workers gebruiken of zwaar leunen op cachingstrategieën in de browser.

De Time to First Byte (TTFB) valt op te delen in de volgende subonderdelen:

Wil je de Time to First Byte optimaliseren? Dit artikel behandelt het cache duration-onderdeel van de Time to First Byte. Wil je de Time to First Byte begrijpen of fixen en weet je nog niet wat cache duration betekent? Lees dan eerst wat de Time to First Byte is en Time to First Byte-problemen opsporen en fixen voordat je aan dit artikel begint.

Let op: meestal is het Cache Duration-onderdeel van de Time to First Byte geen knelpunt. Lees dus vooral verder als a) je een service worker gebruikt, of b) je net als ik een pagespeed-liefhebber bent!

Het cacheDuration-onderdeel van de Time to First Byte is de tijd tussen de waiting time en de DNS-lookup. In deze periode zoekt de browser naar een match in de browser cache of de service worker cache. Laat Real User Monitoring (RUM)-data een hoge cacheDuration zien, dan is de opstart- en lookuptijd van de service worker vrijwel zeker de oorzaak.

Meestal is het cache duration-onderdeel van de Time to First Byte geen knelpunt en duurt dit 10 tot 20 ms. Gebruik je een service worker, dan is minder dan 60ms acceptabel.

Hoe beïnvloeden service workers de Time to First Byte?

Service workers kunnen zowel een positieve als negatieve impact hebben op de Time to First Byte (TTFB), maar alleen bij websites die service workers gebruiken.

Dit is hoe service workers de TTFB beïnvloeden:

Tragere TTFB door opstarttijd van de service worker: De waarde workerStart geeft aan hoelang een service worker erover doet om op te starten als er een aanwezig is voor de opgevraagde resource. Deze opstarttijd telt mee in de TTFB-berekening. Moet een service worker opstarten of ontwaken uit een afgesloten status, dan levert dat vertraging op voor de initiële responstijd en stijgt de TTFB.

Snellere TTFB door caching: Met een caching-strategie als stale-while-revalidate kan een service worker content direct uit de cache serveren als die beschikbaar is. Dit zorgt voor een vrijwel directe TTFB voor veel opgevraagde resources, omdat de browser niet op een server-response hoeft te wachten. Deze strategie werkt het best voor content die weinig verandert, niet voor dynamisch gegenereerde content die actuele data vereist.

Snellere TTFB met app-shell: Bij client-rendered applicaties kan het app-shell-model (waarbij een service worker een basispaginastructuur vanuit de cache levert en content later dynamisch inlaadt) de TTFB voor die basisstructuur tot vrijwel nul verlagen.

Tragere TTFB door niet-geoptimaliseerde code: Complexe en inefficiënte service workers kunnen de cache-lookup vertragen en daarmee ook de TTFB.

Zijn service workers slecht voor pagespeed? Nee, meestal helemaal niet. Weliswaar kunnen service workers de TTFB aanvankelijk verhogen door hun opstarttijd, maar doordat ze network requests onderscheppen, caching beheren en offline ondersteuning bieden, leveren ze op de lange termijn flinke prestatiewinst op — zeker voor terugkerende bezoekers.

Caching-strategieën voor service workers

De caching-strategie van je service worker bepaalt de balans tussen snelheid en versheid. Elke strategie heeft andere gevolgen voor het cache duration-onderdeel van de TTFB:

Cache-First (cache met fallback naar netwerk)

De service worker controleert eerst de cache. Is er een gecachte response aanwezig, dan wordt die direct teruggegeven. Zo niet, dan gaat het request naar het netwerk. Deze strategie levert de snelste TTFB op voor gecachte resources, maar brengt het risico met zich mee dat gebruikers verouderde content te zien krijgen.

Ideaal voor: statische assets, afbeeldingen, fonts en content die zelden verandert.

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((cachedResponse) => {
      if (cachedResponse) {
        return cachedResponse;
      }
      return fetch(event.request).then((networkResponse) => {
        const cache = await caches.open('v1');
        cache.put(event.request, networkResponse.clone());
        return networkResponse;
      });
    })
  );
});

Network-First (netwerk met fallback naar cache)

De service worker probeert altijd eerst het netwerk. Faalt het netwerk-request (bijvoorbeeld omdat de gebruiker offline is), dan wordt de gecachte versie geserveerd. Deze strategie garandeert verse content als er een netwerkverbinding is, maar verlaagt de TTFB niet voor online gebruikers.

Ideaal voor: API-responses, content die vaak wijzigt en pagina's waar actuele data cruciaal is.

Stale-While-Revalidate

De service worker retourneert direct de gecachte versie (snelle TTFB) en haalt tegelijkertijd op de achtergrond een bijgewerkte versie op via het netwerk. Die bijgewerkte versie vervangt het gecachte exemplaar voor het volgende bezoek. Dit levert vaak de beste balans op tussen snelheid en versheid.

Ideaal voor: content die regelmatig verandert maar niet realtime accuraat hoeft te zijn, zoals nieuwsartikelen, blogposts en productoverzichten.

self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.open('v1').then((cache) => {
      return cache.match(event.request).then((cachedResponse) => {
        const fetchPromise = fetch(event.request).then((networkResponse) => {
          cache.put(event.request, networkResponse.clone());
          return networkResponse;
        });
        return cachedResponse || fetchPromise;
      });
    })
  );
});

Configuratie van Cache-Control-headers

Waar het cache duration-onderdeel van de TTFB specifiek de tijd meet die opgaat aan lookups in de service worker en de browsercache, bepalen de juiste Cache-Control-headers of de browser überhaupt contact moet opnemen met de server. Met correcte cache-headers omzeil je voor terugkerende bezoekers in feite de complete TTFB.

Dit is een aanbevolen Cache-Control-configuratie voor verschillende typen resources:

# HTML pages (always revalidate)
Cache-Control: no-cache

# Static assets with content hashing (cache forever)
Cache-Control: public, max-age=31536000, immutable

# Images without content hashing (cache for 1 week)
Cache-Control: public, max-age=604800

# API responses (no caching)
Cache-Control: no-store

De belangrijkste directives uitgelegd:

  • no-cache: de browser moet altijd revalideren bij de server voordat hij een gecachte kopie gebruikt. Dit betekent niet "niet cachen", maar "altijd eerst controleren".
  • no-store: de browser mag de response helemaal niet cachen. Gebruik dit voor gevoelige of sterk dynamische content.
  • max-age: het aantal seconden dat de response vanuit de cache geserveerd mag worden zonder revalidatie.
  • immutable: geeft aan de browser door dat de resource nooit verandert. Combineer dit bij statische assets met bestandsnamen op basis van content hashing (bijv. style.a1b2c3.css).
  • public: zorgt dat de response gecachet mag worden door gedeelde caches (CDN, proxy). Gebruik private voor gebruikersspecifieke content.

Gebruik je een CDN zoals Cloudflare, dan kun je ook edge caching-regels instellen. Lees onze handleiding over Cloudflare configureren voor performance voor gedetailleerde instructies.

Back/Forward Cache (bfcache)

De back/forward cache (bfcache) is een browseroptimalisatie die een complete snapshot van een pagina in het geheugen opslaat zodra de gebruiker weg navigeert. Drukt de bezoeker op de terug- of vooruitknop, dan wordt de pagina direct vanuit het geheugen hersteld. Dit elimineert de TTFB (en elke andere laadmetriek) volledig.

Pagina's die vanuit de bfcache worden geserveerd, tonen in RUM-data een TTFB van 0 milliseconden, omdat er helemaal geen netwerk-request plaatsvindt. De browser herstelt de pagina simpelweg vanuit de snapshot in het geheugen.

Zo zorg je dat je pagina's in aanmerking komen voor de bfcache:

  • Gebruik geen unload-eventlisteners (gebruik in plaats daarvan pagehide).
  • Gebruik geen Cache-Control: no-store op het HTML-document.
  • Sluit openstaande IndexedDB-verbindingen zodra de pagina verborgen wordt.
  • Houd geen actieve WebSocket- of WebRTC-verbindingen open (sluit ze in het pagehide-event).

Je kunt controleren of een pagina geschikt is voor de bfcache in Chrome DevTools onder het tabblad Application, in de sectie "Back/Forward Cache". Chrome toont daar eventuele redenen waarom de pagina niet in aanmerking kwam voor de bfcache.

Voor sites waar bezoekers veel voor- en achteruit navigeren (zoals categorie- en productpagina's in e-commerce of pagina's met zoekresultaten) kan de bfcache de ervaren TTFB voor een groot deel van de navigaties enorm verbeteren.

Hoe meet je het cache duration-onderdeel van de Time to First Byte?

Met dit snippet meet je het cache duration-onderdeel van de Time to First Byte:

new PerformanceObserver((entryList) => {
  const [navigationEntry] = entryList.getEntriesByType('navigation');

  // get the relevant timestamps
  const activationStart = navigationEntry.activationStart || 0;
  const waitEnd = Math.max(
    (navigationEntry.workerStart || navigationEntry.fetchStart) -
    activationStart,
    0,
  );
  const dnsStart = Math.max(
    navigationEntry.domainLookupStart - activationStart,
    0,
  );

  // calculate the cache duration
  const cacheDuration = dnsStart - waitEnd;

  // log the results
  console.log('%cTTFB cacheDuration', 'color: blue; font-weight: bold;');
  console.log(cacheDuration);

}).observe({
  type: 'navigation',
  buffered: true
});

TTFB-problemen door een hoge cache duration opsporen

Wil je zien welke impact echte gebruikers ervaren door de cache duration, dan heb je een RUM-tool zoals CoreDash nodig. Met Real User Monitoring volg je de Core Web Vitals tot in detail.

Navigeer in CoreDash simpelweg naar "Time to First Byte" en bekijk de breakdown-details. Dit toont de TTFB opgesplitst in alle subonderdelen en vertelt je precies hoelang de cacheDuration duurt voor het 75e percentiel.

CoreDash Time to First Byte breakdown: Worker & Cache section shows 81% Good cache duration impact

Hoe beperk je de impact van service worker-cachetijd?

Zo optimaliseer je de TTFB bij het gebruik van service workers:

  • Beperk de complexiteit van service worker-scripts om de opstarttijd te verkorten.
  • Implementeer efficiënte caching-strategieën in de service worker (kies bij voorkeur voor stale-while-revalidate bij navigatie-requests).
  • Overweeg om kritieke resources alvast te pre-cachen tijdens de installatie van de service worker.
  • Monitor en analyseer regelmatig de impact van service workers op de TTFB van je site.
  • Gebruik navigation preload om het netwerk-request parallel aan het opstarten van de service worker te laten lopen. Dit voorkomt dat de opstarttijd van de service worker bij de TTFB wordt opgeteld.

Schakel navigation preload in je service worker in met:

self.addEventListener('activate', (event) => {
  event.waitUntil(
    (async () => {
      if (self.registration.navigationPreload) {
        await self.registration.navigationPreload.enable();
      }
    })()
  );
});

Doe je de implementatie goed, dan maken service workers je site sneller voor terugkerende bezoekers. Doe je het verkeerd, dan betaalt elke page load de opstartkosten.

Verder lezen: optimalisatie-handleidingen

Gerelateerde handleidingen:

  • 103 Early Hints: begin met het laden van kritieke resources nog voordat de server-response klaar is, als aanvulling op je caching-strategie.
  • Cloudflare configureren voor performance: stel CDN edge caching, cache rules en page rules in om je caching-strategie op edge-niveau te optimaliseren.

TTFB-onderdelen: complete handleidingen

De cache duration is een van de vijf subonderdelen van de TTFB. Bekijk de overige onderdelen voor het complete plaatje:

Arjen Karel

Een snellere site nodig?

Ik ben Arjen en ik maak al 17 jaar trage sites snel. Loop je tegen iets aan dat je zelf niet opgelost krijgt? Stuur me je URL, dan praten we even.

Stuur me je URL
Arjen Karel
Arjen Karel, Web performance consultant sinds 2009

Waarom werkt onze fix niet?

Soms serveert het CDN nog de oude HTML, of de fix zit in het desktop-template terwijl mobiel een ander template gebruikt. Stuur me je URL en het probleem, dan stuur ik je een paar momenten. Ik bekijk eerst je field data, daarna besteden we een uur aan je site, en binnen een dag heb je mijn notities op schrift. €350 excl. btw.

Stuur me je URL

Geen developer om de fix te bouwen? Ik doe het werk zelf, op een kopie van je site.

Arjen KarelTTFB nog steeds rood op mobiel?Stuur me je URL