Waarom WooCommerce trager is dan een gewone WordPress-site

Een WooCommerce-shop is geen contentsite met een winkelwagen eraan geplakt. Het is een ander soort WordPress, met een ander verzoekprofiel, een andere druk op de database, en een flink stuk oppervlak dat gewoon niet cachebaar is. Dit artikel legt uit wat WooCommerce écht trager maakt dan een gewone WordPress-site, zodat de rest van de performance-kennisbank voor shopeigenaren hout snijdt.

Een WordPress-site met WooCommerce erop is een fundamenteel andere workload dan een WordPress-site zonder. De cart en checkout kun je niet cachen, de orderpijplijn draait inmiddels op eigen tabellen, de admin-queries lijken niet op die van een contentsite, en WooCommerce-code draait op elk front-end-verzoek, of de pagina nou een product is of een blogpost. Dit artikel gaat over wat dat verschil precies is, zodat je bij een trage shop meteen weet naar welk mechanisme in de rest van de performance-kennisbank je moet kijken.

Wat een WooCommerce-shop een ander soort werk maakt

Vijf structurele dingen onderscheiden een WooCommerce-shop van een contentsite. Stuk voor stuk ontwerpkeuzes, en stuk voor stuk belangrijker dan het formaat van je hostingpakket.

Een flink niet-cachebaar oppervlak. Een contentsite kan het grootste deel van het verkeer uit een full-page cache serveren: identieke HTML aan identieke bezoekers, zonder dat PHP eraan te pas komt. Een WooCommerce-shop kan dat niet, niet op de pagina's waar het geld wordt verdiend. Cart, checkout, my-account en elke pagina die een gepersonaliseerde "recent bekeken" of een ingelogde klantnaam toont, moet de page cache omzeilen (zie hoe WordPress-caching werkt voor het gelaagde model) zodat er per bezoeker andere content teruggestuurd kan worden. Shopoverzichten en categoriepagina's zijn nog wel cachebaar, en dat hoort ook, maar het conversiepad niet. Dat is de reden dat een shop tegelijk een vliegensvlugge homepage én een checkout van 4 seconden kan hebben, en de fix voor het ene heeft niks te maken met het andere.

Bestellingen staan in eigen tabellen. Sinds WooCommerce 8.2 in oktober 2023 is High-Performance Order Storage (HPOS) de standaard opslag voor nieuwe shops. Bestellingen staan niet meer in wp_posts en wp_postmeta; ze staan in eigen tabellen: wp_wc_orders, wp_wc_order_addresses, wp_wc_order_operational_data en wp_wc_orders_meta. WooCommerce claimt dat die verschuiving tot 5x snellere orderaanmaak en tot 40x snellere order retrieval in de backend oplevert, omdat toegewijde tabellen toegewijde indexen dragen en niet hoeven te vechten met het hete wp_posts-pad. Oudere shops die nooit gemigreerd zijn, draaien hun orders nog steeds via wp_posts en wp_postmeta, en het database-drukpatroon uit het artikel over een trage database, plus de WooCommerce database-optimalisatiegids voor HPOS-migratie en orphaned meta cleanup, komt daar harder aan dan bij een HPOS-shop van vergelijkbare omvang.

WooCommerce draait op elk front-end-verzoek, niet alleen op shoppagina's. WooCommerce haakt in op kernacties als plugins_loaded en init, en die acties vuren op elk verzoek, ongeacht of het om een product, een categorie of gewoon een blogpost gaat. Het WooCommerce-codepad, de sessiehandling en de hooks van extensies draaien dus ook op pagina's die niks met de shop te maken hebben. Het WooCommerce-team heeft deze overhead zelf in hun eigen issue tracker als een reëel kostenpunt aangekaart. Nette theme-bouwers gebruiken WooCommerce conditional tags (is_cart(), is_checkout(), is_woocommerce()) binnen template_redirect of init om niet-shop-pagina's over te slaan. De meeste extensies doen dat gewoon niet. Het gevolg: WooCommerce installeren op een blog met een klein shopje erbij maakt elke blogpost trager, niet alleen de shoppagina's.

De admin-queries hebben een andere vorm. Het orderscherm van de WooCommerce-admin draait joins die een contentsite nooit doet. Orderlijsten filteren op status en datum over ordertabellen, rapportages aggregeren per dag over alle historische orders, voorraadschermen kruisen product- en ordertabellen, en extensies voegen eigen kolommen toe die per rij extra lookups draaien. Op een shop met 50.000 bestellingen is dat meetbaar werk elke keer dat een admin het orderscherm opent, en dat telt op zodra meerdere admins tegelijk zijn ingelogd. Het artikel over een trage WordPress-admin legt uit waarom admin-verzoeken sowieso al zwaarder zijn dan front-end-verzoeken. WooCommerce versterkt dat mechanisme.

Extensies draaien in het hete pad van het conversiepad. Een tax-plugin draait bij elke herberekening van de cart. Een shipping-plugin draait bij elke verzendschatting. Een payment gateway draait bij elke checkout-page-load. Een plugin met kortingsregels draait bij elke itemwijziging. Omdat cart en checkout niet cachebaar zijn, draaien al die hooks bij elke klik die een klant door het conversiepad heen maakt. Eén slecht geschreven extensie kan hier een add-to-cart van 200 ms omturnen in eentje van 3 seconden, en het symptoom is niet "een trage pagina" maar "klanten haken af bij de checkout".

Waarom WooCommerce zo ontworpen is

De keuzes die WooCommerce zwaarder maken dan een contentsite zijn dezelfde keuzes die het überhaupt als shopplatform levensvatbaar houden.

Cart en checkout kun je niet cachen omdat de cart persoonlijk is en de checkout transactioneel. Een gecachete cart zou de ene klant de spullen van een andere laten zien. Een cache miss op de checkout kost je een trage pagina. Een cache hit op de verkeerde cart kost je een rechtszaak. WooCommerce neemt de trage pagina voor lief.

HPOS bestaat omdat orders opslaan in wp_posts prima werkte voor kleine shops en omviel bij grote. Posts en postmeta zijn generieke key-value-opslag die geoptimaliseerd is voor content, niet voor transactionele orderdata. Op een grote shop worden ze een contention-hotspot waar elke SELECT voor één order wp_postmeta-rijen aanraakt die tegelijk door elke andere lees-actie op diezelfde tabel worden aangeraakt. Orders in eigen tabellen zetten geeft WooCommerce indexvrijheid en haalt het orderpad uit de gevechtszone met het post-pad.

Uitbreidbaarheid op elk verzoek is dezelfde trade-off die WordPress zelf ook maakt. Een eenmanszaak gebruikt andere verzend-, belasting-, betaal- en voorraadextensies dan een shop met duizend SKU's, en niks daarvan werkt als extensies niet in het verzoek kunnen haken. De prijs is dat elke extensie draait op elk verzoek dat cart of checkout raakt, en dat de shopeigenaar verantwoordelijk is voor het kiezen van extensies die hun werk efficiënt doen.

Wat dit praktisch betekent voor het diagnosticeren van een trage shop

De vorm van de traagheid vertelt je welk mechanisme dominant is. Een paar patronen zie je vaak genoeg om ze meteen te herkennen.

  • Snelle homepage, trage checkout. De page cache doet zijn werk op cachebare URL's en stapt opzij op het conversiepad. Het probleem zit niet in caching; het zit in wat er binnen de niet-cachebare checkout-flow draait: zware payment gateways, synchrone tax- of shipping-API-calls, kortingsregels die over elke cart-regel itereren, of trage queries op wp_wc_orders / wp_wc_order_operational_data. Profile het checkout-verzoek met Query Monitor op staging en de schuldige hook wijst zich meestal binnen dertig seconden aan.
  • Traag op elke pagina, inclusief posts en pages. Het WooCommerce-codepad draait op verzoeken die er eigenlijk niks mee te maken hebben, meestal doordat een extensie zijn werk niet achter shop-conditionals zet. Dit is het toonbeeld dat het WooCommerce-team in hun eigen issue tracker heeft aangekaart.
  • Admin-orderscherm doet er 10+ seconden over op een shop met tienduizenden orders. Óf HPOS staat uit en orders lopen nog via wp_posts / wp_postmeta, óf HPOS staat aan maar een extensie draait een N+1-lookup per orderrij. Staat HPOS uit op een grote shop, dan is inschakelen de grootste enkelvoudige winst die er te halen valt. Staat HPOS aan, dan dekt het artikel over een trage database de N+1- en indexing-mechanica.
  • Alleen traag onder gelijktijdige load (een sale, een campagne, een drop). Het niet-cachebare oppervlak verzadigt de PHP-workerpool als eerste. Elke checkout-bezoeker bezet een worker voor de volle duur van het verzoek, en gelijktijdige checkouts stapelen snel op. Het artikel over PHP workers legt het mechanisme uit, en WooCommerce-shops krijgen het harder te verduren dan contentsites omdat het hete pad niet te cachen valt.
  • Trage admin-orders maar snelle voorkant. Zelfde vorm als het algemene trage WordPress-admin probleem, versterkt door de WooCommerce-specifieke queryvormen op de order- en rapportageschermen.

Wat een trage WooCommerce-shop niet is

Hier lopen de meeste WooCommerce-performance-onderzoeken vast. Een handvol aangrenzende problemen krijgt ten onrechte de schuld van "WooCommerce is traag" en dat kost de meeste uren.

  • Niet een trage voorkant op gecachete pagina's. Als de homepage, de categoriepagina's en de productoverzichten snel zijn en alleen cart, checkout en my-account traag voelen, dan doet de cache precies wat hij moet doen. Het probleem zit in de code die binnen de niet-cachebare flow draait, niet in de cacheconfiguratie. Nog meer caching of een agressievere CDN verandert niks op de pagina's die ertoe doen. De fix zit in de extensiestack die aan cart en checkout hangt.
  • Niet op te lossen met meer RAM. Een shop die traag is door een synchrone externe API-call naar een verzendpartij wordt niet sneller met 16 GB in plaats van 8 GB. Het verzoek staat geblokkeerd op een derde partij, en de worker zit idle te wachten. Meer RAM laat je meer workers draaien, wat helpt voor concurrency, maar doet niks aan het verzoek dat al loopt. "Grotere server" is de duurste niet-oplossing in het WooCommerce-ecosysteem.
  • Niet per se WooCommerce zelf. Een flink deel van wat shopeigenaren ervaren als "WooCommerce is traag" is eigenlijk wp_options autoload-bloat of wp_postmeta-bloat veroorzaakt door andere plugins en jaren aan achtergelaten rommel. De symptomen zien er identiek uit (trage admin, trage paginabuild, trage rapportages) maar de oorzaak is een generiek WordPress-databaseprobleem dat toevallig op een shop draait. Het artikel over een trage database behandelt autoload-bloat en wp_postmeta N+1-patronen uitgebreid. Voordat je WooCommerce de schuld geeft: check Site Health voor de autoload-waarschuwing en kijk of de trage queries op de orderpagina überhaupt wp_postmeta aanraken.
  • Niet op te lossen door van thema te wisselen. Een zwaar thema voegt CSS, JavaScript en render-blocking assets toe aan de browserlaag, en op gecachete pagina's is dat een echte kostenpost. Maar de trage checkout op een shop zit vrijwel nooit in de browserlaag. Die zit in PHP, en het PHP-pad draait op dezelfde manier ongeacht welk thema actief is. Flatsome inruilen voor Storefront maakt de API-call van de payment gateway echt niet sneller.
  • Geen kwestie van het aantal plugins. "Te veel plugins op een WooCommerce-shop" is de verkeerde eenheid. Eén tax- of shipping-extensie die bij elke cart-update een synchrone remote API-call draait doet meer pijn dan dertig kleine extensies die netjes aan shop-conditionals haken. Profilen wat elke extensie doet in cart en checkout is de juiste aanpak. Plugins tellen is een proxy die vaak genoeg klopt om goed te voelen en vaak genoeg faalt om je op het verkeerde been te zetten.

Waar je daarna verder kunt lezen

Gaat het om een conversiepad dat onder load inzakt, dan legt het artikel over PHP workers uit waarom een niet-cachebare checkout als eerste workers verzadigt. Is het admin-orderscherm het pijnpunt, dan behandelt het artikel over een trage WordPress-admin de basismechanica die WooCommerce daarna nog versterkt. Zitten de queries zelf als bottleneck, of dat nou op HPOS-tabellen of op wp_postmeta is, dan dekt het artikel over een trage database indexen, autoload en N+1-patronen. Is de hele publieke site ook traag, dan loopt het overkoepelende artikel over een trage WordPress-site door hoe je de juiste laag isoleert.

Klaar met terugkerende traagheid?

Traagheid komt vaak terug na snelle fixes. Professioneel onderhoud houdt updates, caching en limieten consequent op orde.

Bekijk WordPress onderhoud

Doorzoek deze site

Begin met typen om te zoeken, of blader door de kennisbank en blog.