WordPress browser caching veroorzaakt vaak trage reacties, omdat operators Cache-header verkeerd ingesteld of helemaal niet gecontroleerd. Ik laat je zien hoe typische misconfiguraties 200 retourneren in plaats van 304, waarom TTL's ontbreken en hoe ik caching in WordPress correct kan instellen. Prestaties trim.
Centrale punten
- Lange TTL voor statische activa voorkomt onnodige verzoeken.
- Duidelijke scheiding van statische en dynamische paden beschermt admin en login.
- Eén systeem Gebruik geen concurrerende cachingplug-ins door elkaar.
- Headers controleren met DevTools en 304 status.
- Server caching en browsercache.
Hoe browser caching in WordPress echt werkt
De browser slaat statische bestanden lokaal op, waardoor ze niet opnieuw hoeven te worden geladen. HTTP-verzoeken. Bij het tweede bezoek worden afbeeldingen, CSS en JS uit het lokale geheugen gelezen en wordt alleen de server om wijzigingen gevraagd. Dit vermindert de hoeveelheid gegevens, de responstijden worden korter en scrollen voelt meteen responsiever aan. vloeibaar aan. Als er geen duidelijke instructies zijn, laadt de browser elke keer volledig opnieuw en lijdt de interactieve tijd eronder. Correct ingestelde cache control headers maken 304 validaties mogelijk, verminderen de bandbreedte en verminderen de belasting van PHP en de database. Ik gebruik dit consequent omdat vooral terugkerende gebruikers het meest profiteren van persistent cachen.
Waarom configuratie vaak mislukt
Veel sites leveren statische bestanden met belachelijk korte maximumleeftijd-waarden. Sommige plugins overschrijven elkaars .htaccess en stellen tegenstrijdige directives in. De site markeert beheerpaden vaak verkeerd, waardoor inhoud van /wp-admin of /wp-login.php onbedoeld in de cache terechtkomt en sessies botsen. Ik controleer ook het verschil tussen de eerste en terugkerende aanroep, omdat dit duidelijk de echte gebruikerservaringen verklaart; de vergelijking past hierbij Eerste oproep vs. terugkerende beller. Als je nog steeds query strings gebruikt zonder versiebeheer, zul je oude bestanden in het geheugen aanmaken en je afvragen of verouderd Stijlen.
WP cache headers juist instellen
Ik regel de duur met Cachebeheer en Expires, en ik vermijd dubbelzinnige ETags in omgevingen met meerdere servers. Voor Apache stel ik Expires in op zinvolle waarden en definieer ik „public, max-age“ voor assets. Voor Nginx voeg ik add_header directives toe en zorg ik ervoor dat HTML korte tijden krijgt of „no-store“ als de inhoud gepersonaliseerd is. Ik deactiveer ook ETag headers als loadbalancers of proxies deze waarden niet consistent genereren. Op deze manier dwing ik duidelijk gedrag in de browser af en voorkom ik Revalidaties met elke klik.
VerlopenActief Aan
ExpiresByType image/jpeg "toegang plus 1 jaar".
ExpiresByType image/png "toegang plus 1 jaar".
ExpiresByType text/css "toegang plus 1 maand"
ExpiresByType toepassing/javascript "toegang plus 1 maand"
Header set Cache-Control "public, max-age=31536000" "expr=%{CONTENT_TYPE} =~ m#^(image/|font/|application/javascript)#"
Header ingesteld Cache-Control "no-cache, no-store, must-revalidate" "expr=%{REQUEST_URI} =~ m#(wp-admin|wp-login.php)#"
ETag niet ingesteld # Nginx
locatie ~* .(jpg|jpeg|png|gif|ico|webp|avif|css|js|woff2?)$ {
add_header Cache-Control "public, max-age=31536000";
}
location ~* /(wp-admin|wp-login.php)$ {
add_header Cache-Control "no-store";
}
Uitgebreide cache control directives in het dagelijks leven
Naast „max-age“ en „no-store“ zorgen moderne richtlijnen voor merkbare stabiliteit. „immutable“ geeft aan de browser aan dat een bestand niet zal veranderen zolang de bestandsnaam hetzelfde blijft - ideaal voor assets met versiebeheer. „stale-while-revalidate“ staat toe dat een verlopen kopie wordt afgeleverd terwijl deze op de achtergrond wordt bijgewerkt. „stale-if-error“ houdt een kopie klaar als de Origin kortstondig fouten terugstuurt. „s-maxage“ is bedoeld voor proxies/CDN's en kan andere waarden hebben dan „max-age“. Ook belangrijk: „public“ staat caching toe in gedeelde proxies; „private“ is beperkt tot de browser. „no-cache“ betekent niet „niet cachen“, maar „cachen toegestaan, maar opnieuw valideren voor gebruik“ - een cruciaal verschil met „no-store“.
# Apache 2.4 voorbeeld (cache assets nog robuuster)
Header set Cache-Control "public, max-age=31536000, immutable, stale-while-revalidate=86400, stale-if-error=259200" "expr=%{REQUEST_URI} =~ m#.(css|js|woff2?|png|jpe?g|webp|avif)$#"
Header ingesteld Cache-Control "no-cache, must-revalidate" "expr=%{CONTENT_TYPE} =~ m#^text/html#" # Nginx voorbeeld (304/Include redirects)
locatie ~* .(css|js|woff2?|png|jpe?g|webp|avif)$ {
add_header Cache-Control "public, max-age=31536000, immutable, stale-while-revalidate=86400, stale-if-error=259200" always;
}
locatie ~* .html$ {
add_header Cache-Control "no-cache, must-revalidate" altijd;
} Aanbevolen cache-duur per bestandstype
Ik kies de tijden op basis van veranderingsfrequentie, niet op basis van gewoonte, omdat Activa verouderen heel verschillend. Afbeeldingen, logo's en pictogrammen blijven meestal lang up-to-date, terwijl CSS/JS frequentere iteraties krijgen. Webfonts veranderen zelden, maar vereisen consistente CORS-headers. HTML dient vaak als container voor dynamische inhoud en kan daarom kort of alleen gerevalideerd worden. API's moeten duidelijk gedefinieerde regels hebben zodat clients correct kunnen werken met JSON vermijden.
| Soort bestand | Cache-Controle aanbeveling | Tip |
|---|---|---|
| Afbeeldingen (jpg/png/webp/avif/svg) | openbaar, max-tijd=31536000 | Jaarlijkse cache met bestandsversie gebruiken |
| CSS/JS | openbaar, max-age=2592000 | Voeg versie toe aan bestandsnaam voor updates |
| Lettertypen (woff/woff2) | openbaar, max-tijd=31536000 | Access-Control-Allow-Origin correct instellen |
| HTML (pagina's) | no-cache, must-revalidate of korte max-age | Zeer voorzichtig met dynamische inhoud |
| REST API (json) | private, max-age=0, must-revalidate | Differentiëren naar eindpunt |
Conflicten met plugins vermijden
Ik gebruik maximaal Caching-plugin en controleer of de hosting al regels specificeert op serverniveau. Combinaties zoals W3 Total Cache plus WP Super Cache creëren vaak dubbele directives die elkaar opheffen. WP Rocket is snel in te stellen, maar heeft duidelijke uitsluitingen nodig voor dynamische paden en e-commerce. In ieder geval controleer ik de gegenereerde .htaccess na het opslaan om onlogische headers te herkennen. Vervolgens test ik kritieke pagina's zoals afrekenen, inloggen en gepersonaliseerde dashboards op correcte omzeilen.
Caching en cookies: ingelogde gebruikers, WooCommerce, sessies
HTML voor ingelogde gebruikers mag niet worden opgeslagen in de openbare cache. WordPress plaatst cookies zoals wordpress_ingelogd_, WooCommerce aangevuld woocommerce_items_in_cart, wp_woocommerce_sessie_ en anderen. In plaats van de over Vary: Cookie Ik omzeil caches volledig voor dergelijke verzoeken. Hierdoor blijven afrekenprocessen stabiel en gepersonaliseerde gebieden correct. Ik gebruik ook server-side regels die meer beperkende headers instellen wanneer cookies worden herkend.
# Apache: cookies herkennen en bypass-headers instellen
SetEnvIfNoCase Cookie "wordpress_logged_in_|woocommerce_items_in_cart|wp_woocommerce_session" has_session
Header ingesteld Cache-Control "private, no-store" env=has_session # Nginx: Cookie-gebaseerde omleiding
if ($http_cookie ~* "(wordpress_logged_in|woocommerce_items_in_cart|wp_woocommerce_session)") {
add_header Cache-Control "private, no-store" always;
} Veel cachingplugins bieden hiervoor selectievakjes (WooCommerce/Cart/Exclude checkout). Belangrijk: Nonces (_wpnonce) in formulieren en de Heartbeat API genereren frequente wijzigingen. Ik zorg ervoor dat frontend HTML met nonces niet permanent wordt gecached of werkt via „no-cache, must-revalidate“.
Gerichte behandeling van HTML: gepersonaliseerd vs. algemeen
Niet alle pagina's zijn hetzelfde. Artikelen, landingspagina's en juridische pagina's kunnen vaak in de cache worden opgeslagen met een korte TTL of revalidatie. Archieven, zoekpagina's, dashboards, accountgebieden en checkouts blijven dynamisch. Als er sprake is van pagina-caching, houd ik me aan de volgende praktijk: cache alleen openbare HTML zonder cookies, anders „privé“ of „no-store“. Als je micro-caching test (bijv. 30-60 seconden voor drukbezochte, niet-gepersonaliseerde pagina's), moet je strikte uitsluitingen definiëren voor queryparameters en sessies. WordPress heeft met DONOTCACHEPAGE een constante die sjablonen kunnen instellen op lastige pagina's - ik gebruik deze consequent om fouten te voorkomen.
Server-side caching verstandig combineren
Browser caching eindigt in de client, maar ik ontlast ook de server met pagina, object en opcode cache voor echte Pieken in belasting. Page caching levert statische HTML voordat PHP zelfs maar start. Redis of Memcached verminderen databasequery's voor herhaalde verzoeken en verlagen de TTFB merkbaar. OPcache levert vooraf gecompileerde PHP bytecodefragmenten en verkort zo de uitvoeringstijd. Wat uiteindelijk telt is een schone verbinding tussen de servercache en de browsercache, zodat het tweede bezoek min of meer een succes is. instant werkt.
CDN-integratie zonder verrassingen
CDN's gebruiken hun eigen TTL-logica en reageren op „s-maxage“. Ik maak daarom een duidelijk onderscheid: „max-age“ voor browsers, „s-maxage“ voor Edge. Als er implementaties in behandeling zijn, trigger ik een gerichte zuivering in plaats van globaal „Cache Everything“ te vernietigen. Belangrijk: Cache HTML alleen op de Edge als er geen cookies bij betrokken zijn. Anders worden er onjuiste toestanden gecreëerd omdat de Edge-cache gepersonaliseerde reacties deelt. Voor assets stel ik lange TTL's in en vertrouw ik op versiebeheer van bestandsnamen. CDN's kunnen query strings negeren - nog een reden om versies in de bestandsnaam te houden. Header normalisatie (geen overbodige „Vary“ waarden, consistente „Content-Type“) voorkomt opgeblazen cache sleutels.
Stap voor stap: schone installatie
Ik begin met een plugin en activeer browser caching voor CSS, JS, afbeeldingen en lettertypen voordat ik de .htaccess afronden. Vervolgens stel ik max-age hoog in voor statische assets en voorzie ik HTML van korte tijden of no-cache regels. Ik deactiveer ETags als er meerdere servers bij betrokken zijn en vertrouw op Last-Modified plus 304. Vervolgens activeer ik een preload zodat belangrijke pagina's direct beschikbaar zijn als statische kopieën. Tot slot controleer ik winkel-, aanmeld- en beheerpaden zodat er geen privé-inhoud wordt opgeslagen in de tijdelijke opslag land.
Praktische diagnostiek met CLI en header-controles
DevTools zijn verplicht, maar ik ga dieper met CLI-tests. A curl -I toont koptekst zonder download; met -H Ik simuleer voorwaarden. Ik controleer bijvoorbeeld of revalidaties echt 304 retourneren, of „Leeftijd“ toeneemt vanaf een proxy/CDN en of cookies caching uitschakelen.
# Kopregel weergeven
curl -I https://example.com/style.css
# hervalidatie simuleren (If-Modified-Since)
curl -I -H "If-Modified-Since: Tue, 10 Jan 2023 10:00:00 GMT" https://example.com/style.css
# test met cookie (zou omzeiling moeten forceren)
curl -I -H "Cookie: wordpress_logged_in_=1" https://example.com/ Ik zorg ervoor dat assets een lange „cache control“ waarde hebben, idealiter „immutable“. HTML moet „no-cache“ of een korte TTL hebben. Als ik nog steeds 200 krijg in plaats van 304, zijn er vaak redirects in het spel die ETags/Last-Modified ongeldig maken. Bovendien is „add_header“ in Nginx standaard alleen van toepassing op 200 reacties - met „always“ stel ik ook de headers in voor 304 en 301/302.
Testen en valideren van headers
Ik open DevTools, herlaad de pagina één keer, wis de cache en herlaad om 304 vs. 200 om te observeren. In het netwerkpaneel controleer ik de cachecontrole, de leeftijd, ETag/load-modified en de responsgroottes. Als er nog steeds directe hits zijn in plaats van revalidaties, controleer ik op conflicten met redirects, cookies of query strings. Voor lastige gevallen helpt dit artikel over valkuilen met headers me: Sabotage cache header. Ik herhaal de controle na elke plugin-update omdat wijzigingen in regels vaak geruisloos worden doorgevoerd. pas.
Versiebeheer, CDN en cache-busting
Ik hang de Versie aan bestandsnamen (style.23.css in plaats van style.css?ver=23) zodat browsers lange caches behouden en nieuwe inhoud toch onmiddellijk laden. Een CDN distribueert statische bestanden wereldwijd, stelt zijn eigen TTL's in op edge PoPs en verkort de RTT's drastisch. Belangrijk: Cache HTML alleen in het CDN als er geen personalisatie nodig is, anders worden er verkeerde toestanden aangemaakt. Tijdens het uitrollen verander ik het versienummer automatisch, zodat gebruikers nooit met oude scripts blijven zitten. Zo combineer ik harde browser TTL's met veilige Cache breken.
Schone versiebeheer in WordPress builds
Het meest betrouwbaar is een bouwpijplijn die hashes in bestandsnamen schrijft (bijv. app.9f3c.css). WordPress laadt dan precies dit bestand - browsers kunnen het een jaar lang bewaren dankzij „immutable“. Als fallback, als bestandsnamen niet kunnen worden gewijzigd, stel ik het versienummer dynamisch in op basis van de bestandsdatum. Dit houdt query strings correct en betrouwbaar.
// functions.php (fallback versiebeheer via filemtime)
add_action('wp_enqueue_scripts', function () {
$css = get_stylesheet_directory() . '/dist/style.css';
$ver = file_exists($css) ? filemtime($css) : null;
wp_enqueue_style('theme', get_stylesheet_directory_uri() . '/dist/style.css', [], $ver);
}); Belangrijk: Als de bestandsnaam versies bevat, kan „onveranderlijk“ worden ingesteld. Als je alleen query strings gebruikt, moeten browsers kunnen revalideren zodat updates betrouwbaar aankomen. Ik zorg er ook voor dat build tools oude bestanden opschonen zodat CDN's niet onnodig veel varianten opslaan.
Cache en laad webfonts correct
Webfonts hebben lange TTL's, correcte CORS-headers en optionele preload nodig zodat Sprongen in lay-out verschijnen niet. Ik plaats woff2-bestanden op hetzelfde domein of stel Access-Control-Allow-Origin netjes in. Definieer daarnaast font-display: swap zodat tekst direct zichtbaar blijft terwijl het lettertype aan het laden is. Als je de laadtijd van je lettertypen wilt optimaliseren, vind je hier nuttige tips: Laad webfonts sneller. Met schone cache headers en een preconnect naar CDN's verkort ik FOUT/FOIT merkbaar en zorg ik voor consistente Weergave-Resultaten.
Lettertypen, CORS en Vary correct afstemmen
Fonts van een andere Origin vereisen CORS. Ik stel in Toegangsbeheer-oorsprong toestaan (bijvoorbeeld naar je eigen domein of „*“ voor echt openbaar) en voorkom een onnodige Varieert: Oorsprong, die cache sleutels opblaast. Aanbevolen voor lettertypen: public, max-age=31536000, immutable. Preload verbetert First Paint, maar verandert de TTL niet - preload en hard caching vullen elkaar aan. Ik vergeet ook niet dat gecomprimeerde levering (br/gzip) a Vary: Accept-Encoding is nodig om proxy's correct te scheiden.
Typische foutpatronen en snelle oplossingen
Als er oude code verschijnt na een update, wordt de Versiebeheer op de bestandsnaam. Als de browser elke keer volledig opnieuw laadt, zijn er headers met tegenstrijdige instructies of verwijderen proxies deze onderweg. Als een checkout wordt geannuleerd, cacht de site waarschijnlijk pagina's aan de sessiezijde of API-responses. Als beheerpaden in de cache terechtkomen, ontbreken uitsluitingen voor wp-admin en login of cachingt een plugin globaal. Ik los dit op door stap voor stap te deactiveren, headers te consolideren, kritieke paden uit te sluiten en uiteindelijk het effect met 304 status bevestigen.
Vaak over het hoofd geziene details die een groot verschil maken
- Nginx add_header is niet van toepassing op 304/redirects zonder „altijd“ - cache-headers ontbreken dan voor validaties. Ik stel „altijd“ consequent in.
- Verlopen vs. cachecontrole: „Cache-Control“ heeft prioriteit, „Expires“ dient als fallback voor oude clients. Vermijd dubbele, tegenstrijdige informatie.
- ETag in opstellingen met meerdere servers: Inconsistente ETags vernietigen 304. Ik schakel ETags uit of gebruik zwakke validators en vertrouw op „Last-Modified“.
- Varieer tot een minimum: „Vary: Accept-Encoding“ is verplicht voor compressie, „Vary: Cookie“ vult edge caches - beter omzeilen op basis van cookies.
- SVG en MIME-type: Correct
image/svg+xmlingesteld, geef lange TTL en overweeg inline SVG's voor kritieke pictogrammen. - Vermijd omleidingsketens: Elke 301/302 kan validators verliezen en 200 forceren - schone URL's zonder cascades.
- Gebruik prioriteit/voorbelasting op een gerichte manier:
fetchpriority="hoog"of preload voor kritieke onderdelen versnelt de eerste oproep; caching is effectief voor terugkerende gebruikers. - REST-API onderscheiden: Publieke, zelden veranderende JSON's kunnen kort worden gecached; eindpunten met tokens/cookies strikt „privé“.
Kort samengevat
Ik vertrouw op duidelijke Regelslange TTL's voor assets, korte of gerevalideerde HTML-reacties, versiebeheer en een enkele caching-plugin. Vervolgens combineer ik browser cache met pagina, object en opcode cache om serverbelasting te verminderen. Ik controleer DevTools, zoek naar 304, controleer headers en elimineer conflicten met redirects of cookies. Voor de praktische test vergelijk ik metingen op de eerste en herhaalde oproepen en concentreer me op merkbare verbeteringen. Als je deze stappen volgt, kun je WordPress naar een betrouwbaar niveau van browser caching brengen. Snelheid en houdt gebruikers en zoekmachines tevreden.


