Gå til hovedindhold

Når WooCommerce produktfiltre gør store kataloger langsomme

Hvorfor produktfiltre bliver dyre i WooCommerce

WooCommerce bygger på WordPress’ generelle indholdsmodel, hvor produkter er posts, kategorier og attributter typisk ligger i taksonomier, og mange produktegenskaber ligger i postmeta. Den model er fleksibel, men ikke altid optimal til facetteret filtrering på store kataloger. Ifølge WooCommerce dokumentation om database-tabeller bruger platformen både WordPress-tabeller og egne WooCommerce-tabeller. Når et filterplugin kombinerer data fra flere af disse lag, kan det føre til mange JOINs, store BETWEEN-søgninger på meta-værdier og COUNT-forespørgsler for at vise antal pr. filterværdi.

Det bliver særligt tungt i tre situationer: når attributter er gemt eller læst via postmeta i stedet for taksonomier, når der filtreres på mange kombinationer samtidig, og når kataloget er så stort, at resultatmængderne ikke længere kan findes effektivt via eksisterende indekser. Prisfiltre er et klassisk eksempel. Hvis pris hentes fra metadata og sammenlignes som numerisk værdi, kan databasen få svært ved at bruge indekser effektivt, især hvis pluginet caster tekstværdier til tal undervejs.

  • Filtrering på taksonomier som farve, størrelse og mærke er normalt lettere end filtrering på vilkårlige meta-felter.
  • Kombinationen af filter + sortering + paginering kan være dyrere end hvert element for sig.
  • Antalsberegninger til facetter kan koste næsten lige så meget som selve produktlisten.
  • Variable produkter kan øge kompleksiteten, fordi relationen mellem parent-produkter og variationer ofte kræver ekstra logik.

Typiske symptomer på at filtrene er flaskehalsen

En langsom filterløsning viser sig ikke kun som høj loadtid på hele siden. Ofte ser man, at kategorisider uden filtre er acceptable, men at svartiden stiger kraftigt, når brugeren vælger to eller tre filtre. AJAX-baserede filtre kan også skjule problemet, fordi siden ser moderne ud, men serveren stadig bruger flere sekunder på at generere nyt HTML eller JSON. Det påvirker både oplevet hastighed og serverstabilitet under belastning.

  • Høj TTFB på produktarkiver, især efter valg af filtre.
  • Spikes i CPU og databaseforbrug under crawl eller kampagner.
  • Langsom wp-admin ved produktredigering kan optræde samtidig, hvis databasen generelt er presset.
  • Core Web Vitals kan blive påvirket indirekte, hvis brugerinteraktioner venter på langsomme filterrequests.
  • Hosting-overvågning viser mange samtidige PHP-processer, selv om trafikmængden er moderat.

Sådan måler du problemet korrekt

Det første trin er at skelne mellem frontend-forsinkelse og backend-forsinkelse. Hvis filtrering føles langsom, skal du måle både netværkskaldet fra browseren, PHP-eksekveringstiden og de konkrete SQL-forespørgsler. Ellers risikerer du at optimere det forkerte lag. Hvis et AJAX-kald bruger 2,8 sekunder, men databasen kun står for 150 ms, er problemet ikke primært query performance. Omvendt hjælper frontend-optimering meget lidt, hvis én enkelt SQL-forespørgsel tager 1,9 sekunder.

I praksis bør du bruge query logging, APM eller værktøjer som Query Monitor i et testmiljø. Kig efter de langsomste SELECT-forespørgsler, især dem der gentages mange gange per request. Undersøg EXPLAIN-planen for tunge queries. Her kan du se, om databasen bruger indekser, hvor mange rækker den forventer at scanne, og om den opretter temporære tabeller eller laver filesort. Det er ofte mere nyttigt end at gætte på, om Redis eller mere CPU vil løse problemet.

  • Mål svartid uden filtre, med ét filter og med realistiske kombinationer af filtre.
  • Sammenlign requests for kategorisider, søgninger og AJAX-opdateringer.
  • Gem SQL-eksempler før og efter ændringer, så du kan dokumentere effekten.
  • Se på antal queries per request, ikke kun total loadtid.
  • Kontrollér om object cache reducerer gentagne opslag, men husk at cache ikke gør dyre cache-misses billige.

WordPress’ eget cache-lag er relevant, men det skal forstås korrekt. WP_Object_Cache beskriver object cache som et lag til genbrug af data i hukommelsen, og WordPress performance-dokumentationen om cache forklarer forskellen på cachetyper. Persistent object cache kan aflaste gentagne opslag, men hvis filtrene genererer mange unikke kombinationer, bliver hit-raten ofte begrænset. Derfor er det et supplement, ikke en erstatning for bedre queries og bedre datastruktur.

Den tekniske årsag: meta queries og facetter passer dårligt sammen

Mange langsomme filterløsninger bygger tungt på meta_query. Det er fleksibelt, men dyrt i stor skala. Hver ekstra meta-betingelse kan kræve endnu en JOIN mod wp_postmeta, og den tabel vokser hurtigt i webshops med mange produkter og variationer. Når flere filtre kombineres, kan databasen ende med at scanne store mængder metadata for at finde en relativt lille resultatmængde. Samtidig kan antalsberegninger for facetter kræve yderligere queries med næsten samme kompleksitet.

Taksonomier er ofte bedre til filtrering, fordi relationstabellerne er mere velegnede til opslag på diskrete værdier som farve, størrelse og brand. Hvis du i dag gemmer filterbare egenskaber som fritekst i custom fields, er et af de mest effektive greb ofte at flytte dem til globale attributter eller andre taxonomier. Det ændrer ikke kun SQL-strukturen, men gør det også lettere for eksisterende filterværktøjer at arbejde effektivt.

Praktiske ændringer i data og modellering

  • Flyt filterbare egenskaber fra postmeta til produktattributter eller taxonomier, når værdierne er diskrete og genbruges på tværs af produkter.
  • Undgå at bruge vilkårlige tekstfelter til data, der skal filtreres, sorteres eller tælles.
  • Sørg for konsistente værdier. Hvis samme brand findes i flere stavemåder, bliver både filtrering og cache dårligere.
  • Gennemgå variationer. Nogle filtre bør køre på parent-produktniveau, andre på variationer; en uklar model giver ofte dyre workarounds.
  • Begræns antallet af aktive facetter. Ikke alle felter bør være filterbare bare fordi de kan være det.

WooCommerce anbefaler til produktforespørgsler at bruge de relevante API’er frem for at bygge vilkårlige løsninger oven på rå post-queries. WooCommerce udviklerdokumentationen om produktqueries forklarer, hvordan produktdata abstraheres. Det løser ikke i sig selv performanceproblemet, men det gør det nemmere at holde løsningen kompatibel med WooCommerce’s datalag og eventuelle ændringer i platformen.

Indekser: ofte nødvendige, men skal vælges med omtanke

Når query-mønsteret er kendt, kan databasen ofte hjælpes markant med bedre indekser. Standardindekserne i WordPress-tabellerne dækker ikke alle webshop-scenarier godt nok, især ikke hvis et plugin laver komplekse joins mod postmeta eller sorterer på metadata. Men indekser skal baseres på de faktiske queries i miljøet. Et ekstra indeks hjælper kun, hvis det passer til WHERE-, JOIN- eller ORDER BY-mønsteret.

Typiske kandidater er sammensatte indekser på felter i metadata-tabeller eller relationstabeller, men de bør testes mod EXPLAIN og realistisk belastning. For mange eller for brede indekser kan øge skriveomkostninger og diskforbrug. Derfor bør du starte med de få queries, der står for størstedelen af svartiden. Hvis ét prisfilter står for 40 procent af den samlede databasebelastning, er det dér indsatsen giver mest værdi.

Valg af filterløsning betyder mere end mange forventer

Ikke alle produktfilter-plugins arbejder på samme måde. Nogle bygger næsten alt på standard tax_query og meta_query, mens andre vedligeholder egne indekser, cachelag eller specialtabeller til facetteret søgning. På store kataloger kan den forskel være afgørende. Det er derfor vigtigt at vurdere pluginets datamodel og query-strategi, ikke kun dets funktioner i brugergrænsefladen.

WooCommerce har officiel dokumentation for egne filter- og søgeløsninger, blandt andet Product Filters for WooCommerce og dokumentation om cache i WooCommerce Product Search. Den type dokumentation er nyttig, fordi den viser, om løsningen arbejder med eget cachelag eller optimeret indeksering. Det betyder ikke automatisk, at én løsning er bedst i alle shops, men det giver et bedre grundlag for teknisk vurdering end rene feature-lister.

Hvad Redis og object cache kan og ikke kan

Redis eller anden persistent object cache kan være værdifuld, især når de samme filterkombinationer gentages ofte, eller når WooCommerce og plugins laver mange identiske opslag på tværs af requests. Men ved facetteret filtrering er problemet tit, at brugerne skaber mange unikke kombinationer. Så falder cache-hit-raten hurtigt. Desuden skal den første bruger stadig betale fuld pris for en tung query.

Det betyder ikke, at object cache er irrelevant. Tværtimod kan det være et vigtigt lag til at reducere gentagne taksonomiopslag, options, transient-lignende data og hjælpefunktioner omkring produktvisning. Men hvis EXPLAIN viser store scans i postmeta, bør førsteprioriteten normalt være datamodellering, query-design eller en filterløsning med mere egnet indeksering. Hvis du vil arbejde mere systematisk med cachelaget, kan du også se den interne guide WordPress Object Cache – Skal du vælge Redis eller Memcached?.

Frontend, PHP og hosting: sekundære eller primære årsager?

Selv når databasen er hovedproblemet, bør du stadig kontrollere de andre lag. Nogle filterplugins renderer meget HTML på serversiden eller laver tunge hook-kæder i PHP ved hver opdatering. Andre sender store payloads tilbage til browseren eller triggere flere requests end nødvendigt. Det giver ekstra ventetid oven på de tunge queries. Derfor skal optimering altid skelne mellem database, PHP, frontend og infrastruktur.

Hosting spiller også en rolle, men mest som kapacitetsramme. Langsomme CPU-kerner, presset I/O eller forkert databasekonfiguration kan forværre problemet. Men hvis produktfiltrene er dårligt modelleret, bliver en større server hurtigt en dyr måde at udskyde næste flaskehals. En mere systematisk metode er først at finde det dominerende lag og derefter vælge den mindst indgribende forbedring, der faktisk angriber årsagen. Den tankegang er uddybet i Sådan gør du en langsom WooCommerce-webshop hurtigere.

En praktisk fremgangsmåde til store kataloger

  1. Kortlæg hvilke filtre brugerne faktisk bruger, og hvilke sider der er vigtigst for omsætning og navigation.
  2. Mål de langsomste requests og identificér de 3-5 dyreste SQL-forespørgsler.
  3. Afgør om filterdata ligger rigtigt: taxonomier til diskrete værdier, metadata kun hvor det er nødvendigt.
  4. Test om antalsvisning på facetter kan begrænses eller beregnes mere effektivt.
  5. Vurder om nuværende plugin er egnet til katalogets størrelse, eller om en løsning med bedre indeksering er nødvendig.
  6. Indfør kun ekstra indekser efter test af EXPLAIN og effekt i staging.
  7. Mål igen under realistisk belastning og dokumentér forbedringen i svartid, query-tid og ressourceforbrug.

Hvordan du vurderer om optimeringen virker

En vellykket optimering skal kunne ses flere steder. På databasen bør de tunge queries bruge færre millisekunder og færre scannede rækker. På applikationsniveau bør TTFB falde på filtrerede arkivsider og AJAX-kald. På driftsniveau bør du se mindre CPU-spidsbelastning og færre samtidige PHP-processer under trafik. Og i brugeroplevelsen bør filterhandlinger føles mere direkte, uden at resultatlisten fryser i flere sekunder.

Hvis du også arbejder med de bredere performance-mål i webshoppen, kan det være nyttigt at sætte filtrene ind i en større sammenhæng med stabilitet og Core Web Vitals. Den interne artikel WordPress performance i praksis: sådan gør du hjemmesiden hurtigere og mere stabil giver et godt overblik over, hvordan backend-responstid og frontend-oplevelse hænger sammen.

Konklusion

Langsomme produktfiltre i WooCommerce er sjældent bare et spørgsmål om for lidt serverkraft. På store kataloger skyldes problemet ofte, at facetteret filtrering presses ned over en datamodel, som ikke er ideel til netop den opgave. Derfor starter den rigtige løsning med måling: find de dyreste queries, se hvordan data er modelleret, og afgør om filterløsningen bruger passende indekser og passende tabeller. Først derefter giver det mening at tale om cache, Redis eller hosting. Når data, queries og filterarkitektur passer bedre sammen, kan WooCommerce håndtere store kataloger langt mere stabilt og med en mærkbart bedre brugeroplevelse.

Kilder og yderligere læsning


Kategorier

Denne side er skrevet af

Simon B. H. Christensen
Tlf: 6168 3536