Zum Inhalt springen
Shops & CMS

Filter im Shop-Listing: schnelle Facetten ohne Wartezeit

Jeder Filterklick im Shop zählt zur INP. So bestätigen Sie den Klick sofort, rechnen Zähler sparsam, cachen Ergebnisse und bauen das Listing ruhig neu auf.

19 Min. Lesezeit INPShopwareKategorieseiteFilter

Kurz und einfach erklärt

Viele Shops haben Filter. Damit findet man zum Beispiel alle blauen Jacken. Jeder Klick auf einen Filter soll schnell eine Antwort zeigen.

Am wichtigsten ist das erste Zeichen. Das Häkchen soll sofort erscheinen. Die neuen Produkte dürfen etwas später kommen.

Der Server soll wenig rechnen. Zahlen neben jedem Filter kosten Zeit. Man zeigt sie nur dort, wo sie helfen.

Die Seite soll beim Laden nicht springen. Der Platz für die Produkte bleibt frei, bis sie da sind.

Man misst das mit echten Daten von Besuchern. Wir helfen Ihnen gern dabei.

Ein Klick auf „Blau“ in der Filterleiste, und dann passiert erst einmal nichts: Das Häkchen erscheint verzögert, die Produktkacheln flackern, die Seite rutscht nach oben. Auf Kategorieseiten mit vielen Artikeln ist der Filter eines der wichtigsten Werkzeuge, um aus einer langen Trefferliste die passenden Produkte zu machen, und zugleich eine der teuersten Interaktionen im Shop. Jeder Klick löst eine Kette aus: Der Shop berechnet die Treffer und oft auch die Zähler der übrigen Facetten neu, schickt das Ergebnis zurück, und der Browser baut das Raster der Produktkacheln neu auf. Im Feld geht genau dieser Klick in die Interaction to Next Paint ein, als gut gilt ein Wert von höchstens 200 Millisekunden (web.dev). Dieser Beitrag zeigt am Beispiel von Shopware, wo die Zeit zwischen Klick und Trefferliste bleibt, wie Sie den Klick sofort bestätigen, welche Facetten wirklich Zähler brauchen, wann Suchserver und Ergebnis-Cache helfen, wie das Listing ohne Layoutsprung neu entsteht und wie Sie das Ganze mit Long Animation Frames messen.

Das Wichtigste in Kürze

  • Jeder Filterklick ist eine Interaktion im Sinne der INP: Gemessen wird vom Klick bis zum nächsten gezeichneten Frame, gut sind höchstens 200 Millisekunden (web.dev). Mobile Unterseiten erreichen das nur zu 69 Prozent (HTTP Archive Web Almanac 2025).
  • Der Klick-Handler setzt nur Häkchen und Ladezustand und gibt den Main Thread dann frei. Anfrage, Neuaufbau und Tracking laufen danach, und eine überholte Anfrage bricht ein AbortController ab (MDN Web Docs).
  • Facettenzähler sind Aggregationen. Folgen sie der Auswahl, braucht jede Facette eine eigene gefilterte Berechnung. Zähler gehören nur dorthin, wo sie die Wahl erleichtern; Preis als Spanne, Verfügbarkeit als Schalter ohne Zahl.
  • Bei großen Katalogen gehören Filter auf einen Suchserver: Shopware nennt die Elasticsearch-Anbindung ab mehreren tausend Datensätzen lohnend (Shopware-Dokumentation). Häufige Filterkombinationen beantwortet zusätzlich der HTTP-Cache.
  • Layoutsprünge in den ersten 500 Millisekunden nach dem Klick können aus dem CLS fallen (web.dev), spätere zählen. Das Raster hält darum seine Höhe, bis das Ergebnis da ist. Long Animation Frames zeigen, welches Skript den Neuaufbau bremst.

Warum der Filterklick zur INP zählt

Die Interaction to Next Paint beobachtet alle Klicks, Tipp-Gesten und Tastendrücke während eines Besuchs und meldet am Ende die längste davon, Ausreißer abgezogen (web.dev). Das Häkchen in einer Filterleiste ist ein Klick wie jeder andere, nur hängt an ihm mehr Arbeit als an einem Akkordeon oder einem Menü. Gemessen wird nicht, bis die neuen Treffer da sind, sondern bis der Browser den nächsten Frame zeichnet, der auf den Klick reagiert. Als gut gilt eine INP von höchstens 200 Millisekunden (web.dev), über 500 Millisekunden gilt die Reaktion als schlecht (web.dev). Bewertet wird das 75. Perzentil der Seitenaufrufe, getrennt nach Mobilgeräten und Desktop (web.dev). Wie die Kennzahl grundsätzlich aufgebaut ist, erklärt der Beitrag INP optimieren.

Filter sind eine typische Interaktion nach dem Laden. Nach Nutzungsdaten von Chrome verbringen Besucher 90 Prozent ihrer Zeit auf einer Seite, nachdem sie geladen ist (web.dev). Auf einer Kategorieseite ist das die Zeit, in der gescrollt, gefiltert und sortiert wird. Wer viel filtert, sammelt viele Interaktionen. Bei Seiten mit vielen Interaktionen lässt die INP je 50 Interaktionen die langsamste außen vor (web.dev); die meisten Besuche kommen aber nicht auf so viele Interaktionen. Dann zählt die langsamste voll, und ist das ein Filterklick, bestimmt er die INP des Besuchs.

Wie weit Startseiten und Unterseiten auseinanderliegen, zeigt der Web Almanac. Mobil erreichten 2025 77 Prozent der Websites eine gute INP (HTTP Archive Web Almanac 2025), am Desktop 97 Prozent (HTTP Archive Web Almanac 2025). Auf Seitenebene liegen mobile Startseiten bei 80 Prozent (HTTP Archive Web Almanac 2025), Unterseiten nur bei 69 Prozent (HTTP Archive Web Almanac 2025). Die Autoren weisen darauf hin, dass Unterseiten häufig komplexere Interaktionen wie Filter, Karussells und Formularprüfungen enthalten (HTTP Archive Web Almanac 2025). Dazu kommt das Gerät: 73 Prozent der Online-Shopper ab 16 Jahren in Deutschland kaufen per Smartphone ein (Bitkom 2025), also auf Hardware, die für denselben Neuaufbau in der Regel mehr Zeit braucht als ein Entwicklerrechner. Wie Sie auf solchen Geräten testen, beschreibt der Beitrag Zielgerät statt Testgerät.

Abgrenzung

Hier geht es um das Tempo des Filterklicks. Das Suchfeld behandelt der Beitrag Suchvorschläge ohne Wartezeit, Indexe und langsame Abfragen allgemein der Beitrag zur Datenbank-Query-Optimierung. Welche Filteradressen in den Suchindex gehören und wie Filter auf dem Smartphone bedienbar bleiben, sind eigene Themen und hier ausgeklammert.

Was zwischen Klick und Trefferliste passiert

Bevor sich etwas beschleunigen lässt, muss klar sein, wo die Zeit bleibt. Ein Filterklick in einem serverseitig gerenderten Shop durchläuft typischerweise sechs Stationen, und nur ein Teil davon liegt im Browser:

  1. Eingabe: Der Browser nimmt den Klick an. Läuft gerade ein langes Skript, wartet der Klick. Das ist die Eingabeverzögerung.
  2. Handler: Das Filter-Skript liest den neuen Zustand, baut die Adresse mit den Filterparametern und schreibt sie in die Adresszeile.
  3. Anfrage: Der Shop schickt die Kombination an den Server, oft zusätzlich eine zweite Anfrage für die Facetten.
  4. Server: Er filtert und sortiert die Treffer, lädt die Ergebnisseite und berechnet gegebenenfalls die Aggregationen für die Facettenzähler.
  5. Neuaufbau: Das Ergebnis ersetzt das alte Raster; Stil, Layout und Zeichnen laufen für alle neuen Kacheln.
  6. Nacharbeit: Skripte für Bilder, Merkzettel, Schnellansicht oder Tracking werden für die neuen Kacheln eingerichtet.

Die INP misst davon nur einen Ausschnitt: die Eingabeverzögerung bis zum Start der Handler, die Verarbeitung aller Handler und die Darstellungsverzögerung bis zum nächsten Frame (web.dev). Wartet der Handler nicht auf die Antwort des Servers, endet die Interaktion mit dem Frame, der Häkchen und Ladezustand zeigt. Die Serverzeit fällt dann nicht in die INP dieses Klicks, sie verschwindet aber nicht. Kommt die Antwort, baut der Browser das Raster in eigenen Tasks neu auf. Klickt die Besucherin in dieser Zeit schon den nächsten Filter, wartet dieser Klick auf den Neuaufbau. web.dev beschreibt genau diese Überlappung von Interaktionen als besonders schwierigen Teil der INP-Optimierung (web.dev).

So arbeitet das Standard-Theme von Shopware

Im Quellcode des Shopware-Standard-Themes lässt sich die Kette nachlesen (Shopware-Quellcode, Stand Oktober 2026). Jede Änderung an einer Mehrfachauswahl ruft sofort das Neuladen des Listings auf, ohne Pause dazwischen. Das Listing-Plugin setzt zuerst Ladeklassen an Filterleiste und Produktbereich, schickt die Filter an die Route /widgets/cms/navigation/{navigationId} und verlangt dabei mit dem Parameter no-aggregations ausdrücklich keine Facettenberechnung. Die Antwort ist fertiges HTML, das den Produktbereich ersetzt; danach ruft das Plugin die Initialisierung der Storefront-Plugins für die ganze Seite auf. Die neue Adresse landet per history.pushState in der Adresszeile, und liegt der Anfang des Listings oberhalb des sichtbaren Bereichs, scrollt das Plugin weich dorthin zurück.

Ist in den Einstellungen „Filteroptionen ohne Ergebnisse deaktivieren“ aktiv, kommt eine zweite Anfrage hinzu: an /widgets/cms/navigation/{navigationId}/filter, mit den Parametern only-aggregations und reduce-aggregations (Shopware-Quellcode). Der Server berechnet dann für jede Facette eine eigene, mit der aktuellen Auswahl gefilterte Aggregation, und die Leiste deaktiviert Optionen ohne Treffer. Zwei Dinge fehlen im Standard: Eine laufende Anfrage wird beim nächsten Klick nicht abgebrochen, und die Antworten werden in der Reihenfolge eingesetzt, in der sie eintreffen. Wer drei Farben schnell hintereinander anklickt, löst drei Listing-Anfragen aus, mit aktivierter Einstellung sechs. Trifft eine ältere Antwort nach einer neueren ein, setzt das Plugin auch sie ein.

Das ist kein Fehler im engeren Sinn, denn bei schneller Serverantwort fällt es kaum auf. Bei großen Kategorien, aufwendigen Filtern oder schwachen Smartphones summieren sich genau diese Punkte. Die folgenden Abschnitte gehen sie in der Reihenfolge an, in der sie die Wartezeit bestimmen.

Den Klick sofort bestätigen

Die wichtigste Regel ist die einfachste: Der Klick wird im nächsten Frame sichtbar bestätigt, unabhängig davon, wie lange das Ergebnis braucht. Bis etwa 0,1 Sekunden (Nielsen Norman Group 1993) wirkt eine Reaktion unmittelbar, bis etwa 1,0 Sekunden (Nielsen Norman Group 1993) bleibt der Gedankenfluss erhalten, auch wenn die Verzögerung auffällt. Die Faustregel ist seit Jahrzehnten gängig und passt zur Definition der INP: Für komplexe Interaktionen empfiehlt web.dev, schnell eine erste sichtbare Rückmeldung zu geben, und der nächste Frame ist dafür die früheste Gelegenheit (web.dev).

Für den Filter heißt das: Häkchen setzen, die Option als aktiv markieren, einen dezenten Ladezustand über dem Raster zeigen und dann den Main Thread freigeben. Alles andere läuft danach: Adresse schreiben, Anfrage starten, Tracking-Ereignis senden. web.dev beschreibt dafür ein Muster, das in allen Browsern funktioniert: nicht dringende Arbeit in ein setTimeout innerhalb eines requestAnimationFrame verschieben, damit sie erst nach dem nächsten Frame startet (web.dev). Moderner geht es mit scheduler.yield(), beschrieben im Beitrag Lange Tasks aufteilen. Das folgende Gerüst zeigt die Reihenfolge für ein eigenes Filter-Skript:

filter-listing.js
let controller = null;

function onFilterChange(input) {
  // Sofort sichtbar: Häkchen und Ladezustand
  input.closest('.filter-option').classList.toggle('is-active', input.checked);
  listing.classList.add('is-loading');

  // Alles Weitere erst nach dem nächsten Frame
  requestAnimationFrame(() => {
    setTimeout(() => loadResults(buildFilterUrl()), 0);
  });
}

async function loadResults(url) {
  controller?.abort();              // überholte Anfrage abbrechen
  const own = new AbortController();
  controller = own;
  try {
    const response = await fetch(url, { signal: own.signal });
    renderTiles(await response.text());   // nur die Kacheln ersetzen
    history.pushState(null, '', url);
  } catch (error) {
    if (error.name !== 'AbortError') throw error;
  } finally {
    if (controller === own) listing.classList.remove('is-loading');
  }
}

Ein AbortController steuert den Abbruch einer oder mehrerer Web-Anfragen, sobald das gewünscht ist (MDN Web Docs), hier den der überholten Anfrage des vorigen Klicks. Damit kann keine ältere Antwort mehr ein neueres Ergebnis überschreiben, und der Main Thread verarbeitet keine Antworten, die niemand mehr sehen will. web.dev nennt das Abbrechen ausgehender Anfragen ausdrücklich als Mittel gegen überlappende Interaktionen (web.dev). Bei Mehrfachauswahl kann ein kurzes Entprellen der Anfrage zusätzlich helfen; das Häkchen selbst wird dabei nicht verzögert.

Prüffrage für jedes Filter-Skript

Was muss im nächsten Frame zu sehen sein? Nur das gehört in den Klick-Handler. Alles, was erst mit dem Ergebnis sichtbar wird, also Trefferzahl, Kacheln und deaktivierte Optionen, gehört in die Verarbeitung der Antwort.

Facettenzähler sparsam berechnen

Die Zahl hinter einer Filteroption ist eine Aggregation: Der Server zählt, wie viele Treffer der aktuellen Liste diese Eigenschaft tragen. Für eine einzelne Facette ist das günstig. Teuer wird es, wenn die Zähler der Auswahl folgen sollen. Wer „Blau“ wählt, erwartet bei „Größe“ nur noch die Größen, die es in Blau gibt. Dann braucht jede Facette eine eigene, gefilterte Berechnung, und die Facette „Farbe“ darf ihre eigene Auswahl nicht einrechnen, sonst verschwinden die Alternativen. Suchserver lösen das mit Filtern auf Ebene der Aggregationen und mit einem nachgelagerten Filter, der die Treffer eingrenzt und alle Aggregationsoptionen erhält (OpenSearch-Dokumentation). In Shopware übernimmt das der Parameter reduce-aggregations (Shopware-Quellcode).

FacetteZähler nötig?Günstigere Form
Farbe, MaterialHilfreich bei vielen WertenZähler nur für die sichtbaren Werte, weitere erst beim Aufklappen
GrößeSelten, wichtig ist die VerfügbarkeitNicht verfügbare Größen ausgrauen statt zählen
MarkeBei langen Listen hilfreichWerte nach Häufigkeit ordnen, Zähler optional
Preisnicht enthalten Spanne aus Minimum und Maximum, eine einzige Berechnung
Verfügbarkeit, Versandnicht enthalten Schalter ohne Zahl
BewertungSeltenStufen ohne Zähler

Die Faustregel: Ein Zähler muss eine Entscheidung erleichtern. Zeigt er nur an, dass es Treffer gibt, reicht ein Zustand, verfügbar oder ausgegraut. Preis und Verfügbarkeit brauchen gar keine Zähler. Und nicht jede Facette muss beim ersten Aufbau der Seite berechnet werden: Zugeklappte Facetten können ihre Werte beim Öffnen laden, wenn die Besucherin sie tatsächlich braucht.

In Shopware ist die Stellschraube die Einstellung „Filteroptionen ohne Ergebnisse deaktivieren“. Sie verbessert die Bedienung, weil leere Kombinationen gar nicht erst wählbar sind, kostet aber je Klick die zweite Anfrage mit allen gefilterten Aggregationen. Ob sich das lohnt, zeigt die Messung: Dauert die Filter-Anfrage länger als die Listing-Anfrage selbst, ist sie der erste Kandidat, sei es für einen Index auf dem Suchserver, für den Cache oder für weniger Facetten mit Zählern. Die Einstellung abzuschalten, ist eine Entscheidung über die Bedienung und gehört mit dem Shopteam abgestimmt.

Suchserver statt Datenbank bei großen Katalogen

Filtern, Sortieren und Zählen über viele Eigenschaften ist die Arbeit, für die Suchserver gebaut sind. Shopware formuliert es in der Einrichtungsanleitung zurückhaltend: Ab mehreren tausend Datensätzen lohnt sich die Elasticsearch-Anbindung (Shopware-Dokumentation). Deutlicher wird die Seite zu den Performance-Einstellungen. Für Systeme mit großem Sortiment sei Elasticsearch oder OpenSearch ein Muss, weil die Datenbank ab einer gewissen Sortimentsgröße nicht mehr gut mithält (Shopware-Dokumentation).

Zwei Hinweise aus derselben Dokumentation betreffen direkt das Listing. Erstens sollte im Betrieb mit Suchserver SHOPWARE_ES_THROW_EXCEPTION=1 gesetzt sein. Sonst fällt der Shop bei einem Fehler des Suchservers auf die Datenbank zurück, und die Dokumentation warnt, dass das in großen Projekten die Datenbank vollständig überlasten kann (Shopware-Dokumentation). Zweitens können Listings seit Shopware 6.7.12.0 einen reduzierten Satz an Produktdaten laden (Shopware-Dokumentation), statt der vollen Beschreibung etwa einen Anrisstext von höchstens 512 Zeichen ohne HTML (Shopware-Dokumentation). Neue Installationen haben die Einstellung aktiv, bestehende Shops müssen sie selbst einschalten und vorher prüfen, ob Theme und Erweiterungen in den Kacheln weitere Produktdaten brauchen.

Der Suchserver beschleunigt die Serverseite. An der INP ändert er nur dann etwas, wenn der Browser bisher auf die Antwort gewartet hat oder wenn Besucher schneller klicken, als das Ergebnis kommt. Wo die Serverzeit einer Listing-Anfrage bleibt, ob in der Suche, in der Datenbank oder im Rendern der Vorlage, klären wir in der technischen Analyse.

Ergebnis-Cache je Filterkombination

Viele Besucher filtern dieselbe Kategorie auf dieselbe Weise: Größe M, Farbe Schwarz, nach Preis sortiert. Diese Antworten müssen nicht jedes Mal neu berechnet werden. In Shopware sind die Listing-Route und die Filter-Route für den HTTP-Cache freigegeben (Shopware-Quellcode); jede Kombination ergibt eine eigene Adresse und damit einen eigenen Cache-Eintrag. Eine Einschränkung nennt die Dokumentation: Für angemeldete Kunden und sobald Produkte im Warenkorb liegen, liefert Shopware standardmäßig keine kompletten Seiten mehr aus dem Cache (Shopware-Dokumentation). In B2B-Shops, in denen fast alle angemeldet einkaufen, ist deshalb damit zu rechnen, dass ein großer Teil der Filterklicks den Cache nicht trifft und der Weg ohne Cache selbst schnell genug sein muss.

Die Zahl der möglichen Kombinationen ist allerdings riesig. Ein Rechenbeispiel: Vier Facetten mit je acht Werten, beliebig kombinierbar, ergeben 2 hoch 32 und damit knapp 4,3 Milliarden Kombinationen, ohne Sortierung und Seitenzahl. Vorwärmen lässt sich davon nur ein winziger Teil. Der Cache hilft deshalb vor allem bei den häufigen Kombinationen, und die stehen in den Zugriffsprotokollen: die meistgenutzten Filteradressen der letzten Wochen, je Kategorie. Wie eine Vorwärmliste nach Dringlichkeit entsteht, zeigt der Beitrag Aktionsstart um Mitternacht. Damit der Cache trifft, gelten vier Regeln:

  • Gleiche Kombination, gleiche Adresse: Parameter und Werte in fester Reihenfolge schreiben und leere Parameter weglassen. Sonst landen „Blau, Rot“ und „Rot, Blau“ in zwei Einträgen.
  • Seite und Sortierung bewusst einbeziehen: Sie gehören zum Schlüssel, weil sie das Ergebnis ändern. Kampagnen- und Tracking-Parameter gehören nicht hinein.
  • Verwerfen an Preis und Bestand koppeln: Ändert sich ein Preis oder ein Bestand, müssen die betroffenen Listing-Einträge raus, auch in einem Cache, der vor dem Shop sitzt.
  • Den Kontext beachten: Kundengruppe, Währung und Sprache ändern das Ergebnis und damit den Schlüssel. Wie einzelne Cookies die Trefferquote zerlegen, beschreibt der Beitrag Ein Cookie zerlegt den Cache.

Die Einrichtung des HTTP-Caches, eines vorgeschalteten Reverse-Proxys und der Invalidierung gehört zu unseren Caching-Strategien. Für das Listing zählt am Ende eine Zahl: der Anteil der Filteranfragen, die aus dem Cache kommen, getrennt nach angemeldeten und anonymen Besuchern.

Das Listing ohne Layoutsprung neu aufbauen

Nach dem Klick verschiebt sich auf vielen Kategorieseiten der Inhalt: Das Raster schrumpft, weil weniger Treffer da sind, die Trefferzahl wird breiter, ein Hinweisband erscheint. Für den Cumulative Layout Shift ist entscheidend, wann das passiert. Layoutsprünge innerhalb von 500 Millisekunden nach einer Eingabe tragen eine Markierung und können aus der Berechnung herausfallen (web.dev). Kommt das Ergebnis später, was bei einer langsamen Filter-Anfrage leicht passiert, zählt der Sprung voll. Gut ist ein CLS von höchstens 0,1 (web.dev).

web.dev empfiehlt für genau diesen Fall, sofort Platz zu schaffen und einen Ladehinweis zu zeigen, wenn eine Interaktion eine länger dauernde Anfrage auslöst (web.dev). Für das Listing heißt das:

  • Das Raster behält während des Ladens seine Höhe; die alten Kacheln bleiben stehen und werden abgeblendet, statt zu verschwinden.
  • Die Bildflächen der Kacheln haben ein festes Seitenverhältnis, damit nachladende Bilder nichts verschieben.
  • Trefferzahl, aktive Filter und Sortierung stehen in Bereichen mit fester Höhe.
  • Ein leeres Ergebnis bekommt einen Hinweis in der Höhe einer Kachelreihe statt einer leeren Fläche.
  • Hinweise zur geänderten Auswahl erscheinen in einer vorhandenen Zeile, nicht als neues Band über dem Raster.

Weitere Ursachen und Messwege beschreibt der Beitrag Cumulative Layout Shift vermeiden. Der zweite Hebel ist die Menge, die neu gezeichnet wird. Wird HTML per JavaScript eingefügt, gibt der Browser den Main Thread erst wieder frei, wenn er dieses HTML geparst und gezeichnet hat (web.dev). Bei kleinen Mengen ist das unproblematisch, bei großen verzögert es den nächsten Frame (web.dev) und damit auch den nächsten Filterklick.

Je weniger Kacheln pro Seite und je flacher das Markup einer Kachel, desto kürzer der Neuaufbau. Kacheln unterhalb des sichtbaren Bereichs lassen sich mit content-visibility vom Zeichnen ausnehmen, wie im Beitrag content-visibility beschrieben; Hintergründe zur Knotenzahl stehen im Beitrag DOM-Größe reduzieren. Und wenn nach jedem Neuaufbau alle Plugins der Seite neu eingerichtet werden, lohnt ein Blick darauf, welche davon die neuen Kacheln wirklich brauchen.

Mit Long Animation Frames messen

Ob ein Filter schnell genug ist, entscheiden Felddaten, nicht der Eindruck am Entwicklerrechner. Die Long Animation Frames API meldet jeden Frame, dessen Darstellung sich um mehr als 50 Millisekunden verzögert (Chrome for Developers), und nennt die beteiligten Skripte mit Quelle und Aufrufer, sofern ein Skript länger als 5 Millisekunden lief (Chrome for Developers). Die API ist in Chrome seit Version 123 verfügbar (Chrome for Developers). Lange Tasks beginnen an derselben Schwelle: Was den Main Thread länger als 50 Millisekunden am Stück belegt, gilt als langer Task (web.dev).

Die quelloffene web-vitals-Bibliothek verknüpft diese Frames mit der gemessenen Interaktion. Im Attributions-Build liefert sie zur INP das Element der Interaktion (interactionTarget), die drei Teilzeiten (inputDelay, processingDuration, presentationDelay), die überschneidenden Long Animation Frames und das längste Skript samt der Phase, in der es lief (web-vitals-Bibliothek). Damit lässt sich die INP nach Element gruppieren: Alle Interaktionen, deren Ziel in der Filterleiste liegt, bilden eine eigene Gruppe, getrennt von Warenkorb, Navigation und Galerie. Grundlagen dazu stehen im Beitrag Long Animation Frames. Ein Messplan für die Kategorie-Vorlage:

  1. Felddaten der Kategorieseiten getrennt von Start- und Produktseiten auswerten, mobil und Desktop getrennt, jeweils das 75. Perzentil.
  2. Die INP-Interaktionen nach interactionTarget gruppieren und die Filterleiste herausziehen.
  3. Je Filterklick die größte Teilzeit bestimmen: Eine lange Eingabeverzögerung deutet auf fremde Skripte oder einen laufenden Neuaufbau, eine lange Verarbeitung auf schwere Handler, eine lange Darstellung auf zu viel neues Markup.
  4. Aus den Long Animation Frames die Skripte mit der größten Dauer nach Quelle sortieren: Theme, Erweiterung oder Drittanbieter.
  5. Im Labor dieselbe Klickfolge mit gedrosselter CPU in den Chrome DevTools aufnehmen und daneben die Serverzeit der Listing- und der Filter-Anfrage messen.

Weil der Filterklick die Adresse per pushState ändert und den Inhalt neu aufbaut, kann er künftig auch bei der Messung von Soft Navigations eine Rolle spielen. Was Shops mit Seitenwechseln ohne Neuladen dazu prüfen sollten, steht im Beitrag Soft Navigations in CrUX.

Die Regel für jeden Filter

Im nächsten Frame ist das Häkchen zu sehen, die Anfrage des vorigen Klicks ist abgebrochen, das Raster behält seine Höhe, und der Neuaufbau nach der Antwort bleibt unter der Schwelle eines Long Animation Frame.

Reihenfolge für die Umsetzung

Nicht jede Maßnahme kostet gleich viel. Sinnvoll ist eine Reihenfolge, die mit kleinen Eingriffen im Theme beginnt und erst danach an Server und Infrastruktur geht:

  1. Messen: INP der Kategorie-Vorlage im Feld, Filterklicks per Attribution herausgezogen, dazu die Serverzeit der beiden Anfragen.
  2. Sofort bestätigen: Häkchen und Ladezustand im ersten Frame, Anfrage und Tracking dahinter, überholte Anfragen abbrechen.
  3. Neuaufbau verkleinern: nur die Kacheln ersetzen, den Platz halten, Plugins nur für neue Elemente einrichten.
  4. Facetten prüfen: Zähler nur dort, wo sie bei der Wahl helfen, und die Filter-Anfrage einzeln messen.
  5. Server entlasten: Suchserver für große Kataloge, reduzierte Produktdaten im Listing, Cache für häufige Kombinationen.
  6. Absichern: ein Budget für die INP der Kategorieseite und eine Klickfolge im Labortest, die bei jeder Theme-Änderung mitläuft.

Die ersten drei Schritte liegen im Theme und lassen sich meist ohne Eingriff in die Datenbank umsetzen. Schritt fünf ist eine Entscheidung über die Infrastruktur und lohnt sich vor allem dort, wo die Messung zeigt, dass die Serverzeit den Neuaufbau überholt. Bei der Umsetzung im Shopware-Theme, in der Suche und im Cache unterstützen wir im Rahmen der Shopware-Performance. Die Grundlagen zu INP, LCP und CLS bündelt die Seite Core Web Vitals, für Arbeiten an Skripten und Markup ist die Frontend-Optimierung der Einstieg, und für Shops auf anderen Systemen gilt dieselbe Kette, wie auf der Seite PageSpeed für Onlineshops beschrieben.

Quellen und Dokumentation

Dieser Artikel basiert auf Daten aus: web.dev (Interaction to Next Paint, Optimize Interaction to Next Paint, Optimize input delay, Optimize long tasks, Cumulative Layout Shift); Chrome for Developers (Long Animation Frames API); HTTP Archive Web Almanac 2025 (Kapitel Performance); Bitkom 2025 (Black Friday: Die Hälfte geht auf Schnäppchenjagd); Nielsen Norman Group 1993 (Response Times: The 3 Important Limits); Shopware-Dokumentation (Performance Tweaks, Set up Elasticsearch); Shopware-Quellcode (listing.plugin.js, filter-multi-select.plugin.js, CmsController, AggregationListingProcessor, cms-element-product-listing.html.twig); OpenSearch-Dokumentation (Filter search results); MDN Web Docs (AbortController); web-vitals-Bibliothek (README, INP-Attribution).

Verwandte Artikel

Core Web Vitals & Messung

Soft Navigations in CrUX: was SPA-Shops bis Mai 2027 prüfen

CrUX zeigt seit Oktober 2026 Core Web Vitals mit Soft Navigations. Wer betroffen ist, wie sich LCP, INP und CLS verschieben und was SPA-Shops bis Mai 2027 tun.

17 Min. Lesezeit
Server & Hosting

Aktionsstart um Mitternacht: Cache vorwärmen statt warten

Zum Aktionsstart wechseln die Preise, der Cache wird kalt. Vorwärmliste aus Felddaten und Sitemap, ein Zeitplan für die Nacht und die Trefferquote im Blick.

13 Min. Lesezeit
Grundlagen & Strategie

Was kostet PageSpeed-Optimierung? Aufwand ehrlich planen

Was PageSpeed-Optimierung kostet, entscheiden Vorlagen, Shopsystem, Skripte, Server und Bilder. So planen Sie Analyse, Festpreis, Überwachung und Budget 2027.

16 Min. Lesezeit