Start gratis proefperiode
Skip to content

AJAX vs frontend-first filteren

AJAX-filters bevragen je server en database elke keer dat een gebruiker op een filter klikt, wat zorgt voor 1 tot 3 seconden vertraging bij grote catalogi. Frontend-first filtering (JSON) downloadt een lichtgewicht index bij de eerste paginalading, waardoor de browser duizenden producten direct (onder 5ms) kan filteren zonder de server ooit nog aan te raken. Voor catalogi met meer dan 2.000 producten is frontend-filtering de enige echt schaalbare architectuur voor moderne e-commerce.

De evolutie van WooCommerce-filtering

Als je ooit een WooCommerce-shop hebt gebouwd die groter werd dan een paar duizend producten, dan weet je dat filtering meestal het eerste onderdeel is dat performanceproblemen vertoont. Het begint vaak onschuldig: pagina’s die net iets te traag laden, of een “loading spinner” die net iets te lang blijft staan. Maar naarmate je succes groeit, escaleert dit snel naar database-timeouts tijdens drukke verkoopperiodes en gefrustreerde klanten die je shop verlaten omdat ze niet snel kunnen vinden wat ze zoeken. De frustratie van de klant is direct meetbaar in je conversieratio en de uiteindelijke omzet van je onderneming.

De hoofdoorzaak van deze problemen is bijna altijd architecturaal. De manier waarop een filterplugin je data bevraagt en het resultaat aan de browser levert, bepaalt het absolute plafond van de performance. Hardware kan veel oplossen (snellere CPU’s, meer RAM), maar een inefficiënte architectuur zal uiteindelijk elke server op de knieën krijgen zodra de catalogus of het verkeer groeit. In de afgelopen tien jaar is WooCommerce-filtering geëvolueerd door drie duidelijke generaties van architectuur, elk met zijn eigen sterke punten en beperkingen:

  1. Generatie 1: Standaard WP_Query + AJAX (De basislijn waar de meeste plugins op draaien)
  2. Generatie 2: Index-gebaseerde AJAX (Het model gepopulariseerd door FacetWP)
  3. Generatie 3: Frontend-first / Client-side (De architectuur van InstantFilter)

Welke filterarchitectuur past bij jouw WooCommerce-shop?

Bij het zoeken naar een “WooCommerce product filter plugin” vergelijken de meeste webshopeigenaren alleen de functies aan de voorkant: Heeft het mooie kleurensamples? Kan het filteren met een soepele prijsschuifregelaar? Ondersteunt het specifieke product add-ons voor variaties? Hoewel deze functies belangrijk zijn voor de UX, is de onderliggende architectuur wat bepaalt of je site overeind blijft tijdens een piek in het verkeer, zoals op Black Friday of tijdens een grote marketingcampagne. Een prachtige sidebar is waardeloos als de server er 2 seconden over doet om de resultaten te tonen. De technische fundering is de onzichtbare motor van je verkoopsucces.

Als je kiest voor een plugin met een Generatie 1 architectuur, zal geen enkele hoeveelheid server-caching of dure hosting je redden wanneer het verkeer echt toeneemt. Om een weloverwogen beslissing te nemen die de toekomst van je shop veiligstelt, moet je begrijpen hoe deze drie generaties onder de motorkap werken en wat de impact is op je serverbronnen, je SEO en de uiteindelijke conversieratio. De keuze voor architectuur is een strategische keuze voor de lange termijn die bepaalt hoe schaalbaar je bedrijf werkelijk is.

Generatie 1: Standaard WP_Query & AJAX

Dit is hoe de overgrote meerderheid van de gratis en instap-filterplugins werkt. Het is de meest eenvoudige manier om filters te bouwen omdat het direct gebruik maakt van de ingebouwde functies van WordPress. Wanneer een shopper klikt op “Blauw” en “Maat M”, stuurt de plugin een AJAX-verzoek naar de server. De server moet vervolgens de volledige WordPress-omgeving laden (inclusief alle actieve plugins en het thema) en een massieve WP_Query construeren om de resultaten te vinden.

Omdat WooCommerce productdata verspreid over meerdere tabellen opslaat (wp_posts voor de basis, wp_postmeta voor prijzen en wp_term_relationships voor attributen), vereist deze query zware JOIN-operaties. Een enkel filterverzoek kan er onder de motorkap als volgt uitzien:

SELECT SQL_CALC_FOUND_ROWS wp_posts.ID
FROM wp_posts
LEFT JOIN wp_term_relationships ON (wp_posts.ID = wp_term_relationships.object_id)
INNER JOIN wp_postmeta ON ( wp_posts.ID = wp_postmeta.post_id )
WHERE 1=1
AND wp_posts.post_type = 'product'
AND wp_posts.post_status = 'publish'
AND ( wp_postmeta.meta_key = '_price' AND CAST(wp_postmeta.meta_value AS SIGNED) < 50 )
GROUP BY wp_posts.ID
ORDER BY wp_posts.post_date DESC

Het probleem met deze aanpak is dat SQL-queries met veel JOINs en meta-queries exponentieel trager worden naarmate de database groeit. De wp_postmeta tabel is vaak de grootste tabel in een WooCommerce database en het doorzoeken van miljoenen rijen voor elke filterklik is simpelweg niet schaalbaar. Bij 10.000+ producten kan een enkele klik op een filter de database secondenlang bezighouden. Bovendien herhaalt dit proces zich voor elke bezoeker, wat de serverbelasting tot onbeheersbare hoogtes kan stuwen en uiteindelijk kan leiden tot server-crashes.

De Voordelen

  • Real-time nauwkeurigheid: Bevraging van de live database, dus voorraadwijzigingen zijn direct zichtbaar.
  • Eenvoudig te bouwen: Maakt gebruik van de standaard WordPress API’s en hooks.
  • Lage kosten: Vaak gratis of zeer goedkoop beschikbaar.

De Nadelen

  • Slechte schaalbaarheid: JOINs op meta_query en tax_query worden onwerkbaar traag bij grotere catalogi.
  • Hoge serverbelasting: Elke klik triggert een zware databaseberekening die PHP-workers bezet houdt.
  • Geen caching: AJAX-verzoeken omzeilen vaak de standaard paginacache, waardoor de server elke keer vol aan de bak moet.

Generatie 2: Index-gebaseerde AJAX

Naarmate catalogi groter werden en webshopeigenaren meer eisten van hun filters, realiseerden developers zich dat het direct bevragen van de ruwe WordPress-tabellen onhoudbaar was. Dit leidde tot de tweede generatie: Index-gebaseerde filtering. Plugins zoals FacetWP pionierden hiermee in de WordPress-wereld en boden een enorme sprong voorwaarts in stabiliteit en snelheid voor middelgrote catalogi die de standaard WordPress-limieten ontgroeiden.

In plaats van wp_postmeta on-the-fly te bevragen, vereisen deze plugins dat je je producten vooraf “indexeert”. Ze scannen je catalogus en bouwen een geoptimaliseerde, platte tabel op (bijv. facetwp_index). Deze tabel koppelt elk product-ID direct aan de bijbehorende filterwaarden (facets). In plaats van door miljoenen rijen metadata te moeten graven via trage JOINs, kan de database nu in één simpele scan zien welke producten aan de criteria voldoen. Dit is een enorme winst voor de database-gezondheid en de algehele stabiliteit van de server.

Wanneer een shopper op een filter klikt, stuurt de plugin nog steeds een AJAX-verzoek naar de server. De database-query is nu echter razendsnel omdat deze alleen de geoptimaliseerde indextabel hoeft te raadplegen. Dit lost de database-bottleneck voor een groot deel op en maakt de interactie merkbaar sneller dan bij Generatie 1.

De bottleneck verschuift: Hoewel de database-query nu snel is, blijft de architectuur fundamenteel afhankelijk van AJAX. Elke interactie vereist een volledige “round-trip”: Browser → Netwerk → PHP → Database → PHP → Netwerk → Browser.

Zelfs als de database-query slechts 5ms duurt, voegt de netwerklatency (de tijd die nodig is om de verbinding op te zetten en data te versturen) vaak 200ms tot 500ms toe aan elke interactie. Bovendien moet de server voor elke klik de volledige WordPress-omgeving opstarten om het verzoek af te handelen, wat kostbaar geheugen en CPU-tijd verbruikt die niet voor andere taken gebruikt kan worden.

De AJAX-belasting en Concurrency

Als 100 shoppers tegelijkertijd filteren, dwingt een index-gebaseerde AJAX-plugin je server nog steeds om 100 gelijktijdige PHP-verzoeken af te handelen. De database overleeft het dankzij de index, maar je PHP-workers kunnen gemakkelijk hun limiet bereiken. Dit resulteert in een trage site voor iedereen, niet alleen voor degenen die filteren. Dit kan leiden tot een sneeuwbal-effect van vertragingen die de hele gebruikerservaring verpesten.

MetriekGen 1: Standaard AJAXGen 2: Index AJAX
Database Query TijdTraag (Zware JOINs)Snel (Platte Tabel)
Server PHP BelastingHoog (Volledige WP Boot)Gemiddeld (Volledige WP Boot)
Netwerklatency200ms+ per klik200ms+ per klik
SchaalbaarheidLaag (tot ~1.000 producten)Medium (tot ~10.000 producten)

Generatie 3: Frontend-first (Hydrated)

Als de database niet langer de bottleneck is, is de enige manier om nog sneller te worden het volledig elimineren van de netwerk-round-trip. Dit is de Frontend-first of Client-side architectuur, de technologie die InstantFilter aandrijft. Het is een fundamentele verschuiving van “de server berekent alles bij elke klik” naar “de browser handelt de interactie onmiddellijk af”.

Net als bij Generatie 2 indexeert InstantFilter je catalogus in geoptimaliseerde tabellen (wp_if_*). Maar in plaats van te wachten op AJAX-verzoeken om deze data te bevragen, gaat het een cruciale stap verder: het compileert die index naar een hoogwaardig gecomprimeerd JSON-bestand, het zogenaamde Codebook. Dit bestand bevat alle informatie die nodig is om te filteren, maar dan in een formaat dat extreem snel door de JavaScript-engine van de browser gelezen en geparsed kan worden.

De Hydratatie-fase: Het beste van twee werelden

Wanneer een shopper op je categoriepagina landt, gebruikt InstantFilter Server-Side Rendering (SSR) om het initiële HTML-grid te tonen. Dit is essentieel voor SEO (zoekmachines kunnen de producten zien) en een snelle eerste weergave voor de gebruiker. De pagina ziet er direct compleet uit en is direct bruikbaar voor de klant, wat de bounce-rate verlaagt.

Echter, op de achtergrond downloadt de browser het gecomprimeerde JSON Codebook. Zodra dit binnen is, wordt de pagina “gehydrateerd”. De JavaScript-engine in de browser neemt de filterlogica volledig over van de server. Het is alsof de browser een intelligente kopie van je database in zijn geheugen krijgt, specifiek geoptimaliseerd voor razendsnelle filtering.

Wanneer de shopper nu op “Blauw” klikt, is er geen AJAX-verzoek meer nodig. De JavaScript filtert de lokale JSON-data en update de DOM onmiddellijk. Interactietijden dalen van ~300ms (AJAX) naar ~1,5ms tot 5ms (Lokale JS). Dit voelt voor de gebruiker als een native app op een smartphone: onmiddellijk, vloeiend en zonder enige vorm van hapering of wachttijd.

Nul Serverbelasting tijdens het browsen

Omdat het filteren volledig in de browser van de shopper gebeurt, doet je server absoluut niets tijdens het browseproces. 1.000 gelijktijdige shoppers die lokaal filteren, leggen nul beslag op je PHP-workers en database. Je hostingrekening blijft laag terwijl je UX naar een ongekend niveau stijgt. Je server kan zich volledig focussen op het afhandelen van de daadwerkelijke bestellingen en betalingen.

Waarom JSON sneller is dan HTML-fragmenten

Bij AJAX-filters stuurt de server vaak volledige HTML-fragmenten terug voor het productgrid. Dit is zware data die geparsed moet worden door de browser en die veel bandbreedte verbruikt. Een JSON-codebook daarentegen bevat alleen de rauwe data (ID’s, prijzen, attribuut-ID’s). Een catalogus van 5.000 producten kan vaak gecomprimeerd worden tot minder dan 100KB. Het downloaden van dit kleine bestand één keer is veel efficiënter dan het herhaaldelijk versturen van HTML-grids over het netwerk bij elke klik. Bovendien kan JSON direct door de JavaScript-engine van de browser worden verwerkt zonder dat er complexe string-manipulaties nodig zijn, wat de belasting op het apparaat van de klant minimaliseert en de batterijduur spaart.

Ontwikkelaarservaring (DX): Bouwen met data vs templates

Voor developers biedt de frontend-first aanpak een nieuwe manier van werken die veel meer vrijheid geeft. In plaats van te worstelen met PHP-templates en complexe AJAX-hooks, werk je direct met de data in de browser. Dit maakt het eenvoudiger om complexe interacties te bouwen, zoals real-time updates van andere elementen op de pagina wanneer een filter wordt geselecteerd. Omdat de staat van de filters volledig in JavaScript wordt beheerd, is het integreren van moderne frontend-technieken veel natuurlijker dan bij traditionele server-side rendering. Je kunt hiermee een ervaring creëren die voorheen alleen mogelijk was met maatwerk-oplossingen of headless e-commerce systemen.

Afwegingen: Welke architectuur wint wanneer?

Er bestaat geen perfecte architectuur voor elke denkbare situatie; er zijn altijd technische afwegingen. De keuze hangt af van je catalogusgrootte, de complexiteit van je data en je ambities op het gebied van performance. Hier is hoe je kiest op basis van de vereisten van jouw project en de verwachtingen van je doelgroep:

Kies voor Frontend-first (InstantFilter) als:

  • Snelheid cruciaal is: Je wilt app-achtige interacties zonder enige vertraging voor de beste UX.
  • Veel verkeer: Je wilt je server beschermen tegen honderden gelijktijdige PHP-verzoeken tijdens piekmomenten.
  • Conversie-optimalisatie: Je weet dat elke milliseconde vertraging geld kost in e-commerce.
  • Focus op WooCommerce: Je bouwt een dedicated shop met een catalogus tot ~50.000 producten.

Kies voor Index AJAX (FacetWP) als:

  • Gemengde content: Je moet naast producten ook blogposts, directories en custom post types filteren in één interface.
  • Gigantische datasets: Als je catalogus de 100.000+ producten overstijgt, kan een JSON-payload te groot worden voor mobiele browsers.
  • Complexe add-ons: Je leunt zwaar op dynamische prijsberekeningen of externe API’s die per verzoek op de server moeten plaatsvinden.

De impact op SEO en Crawl Budget

Een veelvoorkomend misverstand is dat frontend-filtering slecht zou zijn voor SEO omdat de data in JavaScript staat. Dit is alleen waar als de plugin geen SSR (Server-Side Rendering) ondersteunt. Omdat InstantFilter de eerste paginalading als statische HTML serveert, zien Google-bots precies wat ze moeten zien: een volledig gevuld productgrid en werkende links. Het grote voordeel is zelfs dat je “crawl budget” bespaart. Omdat de filters geen duizenden unieke AJAX-URL’s of query-strings genereren die de bot moet proberen te volgen, blijft de indexering van je shop schoon en gefocust op je belangrijkste pagina’s. Je voorkomt hiermee ook “keyword cannibalization” waarbij Google niet meer weet welke filtercombinatie het belangrijkste is, wat je rankings op de lange termijn ten goede komt.

Beveiliging en Concurrency: Bescherm je server tegen misbruik

AJAX-filters kunnen onbedoeld een kwetsbaarheid vormen voor je server. Kwaadwillende bots kunnen duizenden filtercombinaties in korte tijd aanvragen, wat in feite een Denial of Service (DoS) aanval op je PHP-workers simuleert. Omdat elk verzoek de server dwingt om zwaar werk te verrichten, kan dit je site platleggen voor echte klanten. Bij frontend-filtering is dit risico minimaal. De bot downloadt het JSON-bestand één keer (wat door de server als een statisch bestand wordt afgehandeld) en alle verdere “aanvallen” vinden plaats in de browser van de bot zelf, zonder je server te belasten. Dit maakt je infrastructuur aanzienlijk robuuster en veiliger tegen onvoorziene pieken in bot-verkeer.

Mobiele performance: De echte lakmoesproef voor e-commerce

Op mobiele apparaten is netwerklatency veel merkbaarder dan op een desktop met een stabiele glasvezelverbinding. Een 4G-verbinding heeft vaak een hogere “Round Trip Time” (RTT). Bij AJAX-filters wordt deze vertraging bij elke klik gevoeld. Een shopper die drie filters aanklikt, wacht in totaal misschien wel 3 tot 5 seconden op resultaten. In die tijd kan de aandacht verslappen en de shopper de site verlaten. Bij frontend-filtering is de wachttijd na de eerste paginalading exact nul. Zodra het Codebook binnen is, reageert de site onmiddellijk op elke aanraking, wat de kans op een aankoop aanzienlijk vergroot en de algehele merkbeleving versterkt. In een mobiele wereld is snelheid geen luxe meer, maar een absolute noodzaak.

Verdiep je verder

Ontdek onze andere technische gidsen en vergelijkingen over WooCommerce performance:

Veelgestelde vragen over filterarchitectuur

AJAX-filtering stuurt een verzoek naar je server elke keer dat een gebruiker op een filter klikt, wacht tot de server de resultaten heeft berekend en update dan de pagina. Frontend-filtering (zoals InstantFilter) downloadt een gecomprimeerde database (JSON) bij de eerste paginalading. Alle volgende filterklikken worden direct in de browser berekend, zonder opnieuw contact op te nemen met de server.
Nee. InstantFilter maakt gebruik van Server-Side Rendering (SSR) voor de initiële paginalading. Dit betekent dat Google-bots exact hetzelfde HTML-grid en dezelfde productlinks zien als bij een standaard WooCommerce-setup. De frontend-filtering engine neemt het pas over nadat de pagina volledig is geladen voor menselijke bezoekers.
Ja, maar er is een praktische grens. Omdat de browser het JSON “codebook” moet downloaden, groeit de grootte van de initiële download mee met je catalogus. InstantFilter gebruikt geavanceerde compressie en optimalisatie, waardoor het extreem snel is voor catalogi tot wel 50.000 producten. Voor catalogi die de 100.000 producten overstijgen, kan de JSON-payload te groot worden voor trage mobiele verbindingen, in welk geval een index-gebaseerde AJAX-aanpak de voorkeur kan hebben.
De meeste filterplugins gebruiken AJAX om bij elke klik de WordPress-database te bevragen. Als je een grote catalogus hebt, worden deze SQL-queries (die meerdere meta-tabellen koppelen via JOINs) erg traag. Bovendien dwingt elk AJAX-verzoek je server om de volledige WordPress-kern op te starten, wat PHP-workers verbruikt en vertragingen veroorzaakt voor alle bezoekers, ook degenen die niet filteren.
Ja, sterker nog, het werkt er beter mee samen. Omdat frontend-filters geen dynamische AJAX-verzoeken sturen die de cache omzeilen, kunnen je categoriepagina’s 100% statisch geserveerd worden vanuit de cache van WP Rocket of Redis. Dit verlaagt de Time to First Byte (TTFB) aanzienlijk.

Klaar om filteren instant te maken?

Start je 14-daagse proefperiode. 30 dagen geld-terug-garantie — op elk moment opzegbaar.