aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Webontwikkeling

Laravel Cache: praktische gids voor performance

Een degelijke Laravel cache-strategie is vaak de snelste prestatiewinst die je een applicatie kunt geven. Elke gang naar de database, elke externe API-aanroep en elke zware pagina-render kost tijd; die resultaten één keer berekenen en opslaan in plaats van ze bij elke request opnieuw uit te rekenen kan responstijden terugbrengen tot milliseconden. In deze gids behandel ik cache-drivers, het cachen van queries en pagina's, en het meest kritische onderwerp van allemaal — de cache veilig invalideren — met praktische voorbeelden.

Wanneer helpt caching echt?

Caching schittert bij data die duur is om te produceren maar zelden verandert. Typische kandidaten zijn:

  • rapportagequery's met zware JOINs of aggregatie,
  • menu's, instellingen of categorielijsten die op elke pagina staan,
  • trage of gelimiteerde externe API-antwoorden (wisselkoersen, weer),
  • HTML-uitvoer van hele pagina's die weinig verandert.

Daarentegen is gebruikersspecifieke data die direct correct moet zijn (winkelmandsaldo, betaalstatus) meestal het verkeerde om te cachen. De eerste regel is: meet eerst. Cache de plek waarvan je hebt bewezen dat hij traag is.

De juiste driver kiezen

De cache-laag van Laravel is driver-onafhankelijk; de configuratie staat in config/cache.php, en de standaard store wordt bepaald door de variabele CACHE_STORE in je .env-bestand. De belangrijkste opties zijn:

  • file — geen installatie, prima voor kleine single-server projecten.
  • database — persistentie zonder extra service; goed voor matige belasting.
  • redis / memcached — de aanbevolen keuze voor veel verkeer, meerdere servers en tag-ondersteuning.
  • array — leeft alleen tijdens één request; handig in tests.

Verwacht je serieus verkeer in productie, dan is Redis vrijwel altijd het juiste antwoord. De configuratie ziet er zo uit:

# .env
CACHE_STORE=redis
REDIS_HOST=127.0.0.1
REDIS_PORT=6379

Query-caching: het remember-patroon

De meest gebruikte API is Cache::remember(): hij geeft de waarde terug als de sleutel bestaat, voert anders de closure uit, slaat het resultaat op en geeft het terug. Dit perst de logica "haal op indien aanwezig, anders bereken en sla op" samen in één regel.

use Illuminate\Support\Facades\Cache;

$populair = Cache::remember('projects:populair', now()->addHour(), function () {
    return Project::where('is_published', true)
        ->orderByDesc('views')
        ->take(10)
        ->get();
});

De duur kan een DateTime zijn (now()->addHour()) of een aantal seconden. Wil je dat het nooit verloopt, gebruik dan Cache::rememberForever() — maar dan is invalidatie volledig jouw verantwoordelijkheid.

Er zijn ook helpers op een lager niveau:

Cache::put('sleutel', $waarde, now()->addMinutes(10));
$waarde = Cache::get('sleutel', 'standaard');
Cache::has('sleutel');
Cache::forget('sleutel');
Cache::increment('bezoek_teller');

Hele pagina's en fragmenten cachen

Wanneer query-caching niet genoeg is, kun je ook gerenderde HTML opslaan. Een eenvoudig patroon op controllerniveau:

public function index()
{
    $html = Cache::remember('home:html', now()->addMinutes(15), function () {
        return view('site.index', $this->laadData())->render();
    });

    return response($html);
}

Wil je het hele antwoord op HTTP-niveau cachen, dan is dat netter in een middleware: gebruik de request-URL als sleutel, controleer hem met Cache::has(), en genereer en bewaar het antwoord als hij ontbreekt. Op statische showcasepagina's brengt deze aanpak de databasebelasting tot vrijwel nul terug.

Tags en veilige invalidatie

Het moeilijke aan caching is niet het opslaan, maar op het juiste moment invalideren. Wanneer een project wordt bijgewerkt, moet je alle gerelateerde cachesleutels verwijderen. Gebruik je Redis of Memcached, dan maken tags dit elegant:

Cache::tags(['projects'])->put('projects:populair', $data, 3600);

// Wanneer een project verandert:
Cache::tags(['projects'])->flush();

Tags worden niet ondersteund door de file- en database-drivers; verwijder in dat geval de sleutels handmatig. De robuustste methode is inhaken op model-events:

// In het Project-model
protected static function booted(): void
{
    static::saved(fn () => Cache::forget('projects:populair'));
    static::deleted(fn () => Cache::forget('projects:populair'));
}

Via de commandoregel, om de volledige applicatiecache te legen:

php artisan cache:clear

Config-, route- en view-caches

Er is een aparte laag die je niet moet verwarren met het cachen van applicatiedata: de eigen caches van het framework. Op een productieserver levert het draaien van deze commando's na de deployment echte snelheidswinst op:

php artisan config:cache
php artisan route:cache
php artisan view:cache
# alles in één keer:
php artisan optimize

Belangrijke kanttekening: wanneer config:cache actief is, werken env()-aanroepen alleen betrouwbaar binnen configuratiebestanden. Roep env() niet rechtstreeks aan in je code — lees waarden via config(). Wanneer je de configuratie wijzigt, herbouw je hem met php artisan config:clear.

Veelgestelde vragen

Waarom verschijnen mijn wijzigingen niet tijdens het ontwikkelen?

Je krijgt hoogstwaarschijnlijk een verouderde cache geserveerd. Het commando php artisan optimize:clear leegt de config-, route-, view- en applicatiecache in één keer; het is het eerste wat je probeert als er lokaal iets misgaat.

Moet ik file of Redis gebruiken?

Voor een kleine single-server site is de file-driver ruim voldoende. Stap over op Redis als je veel verkeer, meerdere servers, atomische tellers of tag-gebaseerde invalidatie nodig hebt.

Hoe lang moet de cache-TTL zijn?

Dat hangt af van hoe verouderd de data mag zijn. Voor lijsten die elk uur veranderen is 15–60 minuten redelijk; voor data die bijna nooit verandert is rememberForever() plus event-gebaseerde invalidatie het meest efficiënt.

Wil je de prestaties laten vliegen met een goed ontworpen cache? Laten we samen de trage plekken van je Laravel-applicatie meten en de juiste cachestrategie bouwen — neem contact met me op.

Devamı için