Wer einen Shop mit +200 Kategorien und mehreren Kundengruppen hat kennt sicher das Problem. Beim initialen Aufruf der Seite nach einem Deployment oder beim Login mit einer „not cached“ Seite kann man sich ein Snickers schnappen. Wie Ihr das ganze umgeht zeige ich euch hier kurz…
Erweitertes Menü
Das erweiterte Menü iteriert kurz gesagt durch die Shop Hauptkategorie und listet je nach „Anzahl der Ebenen“ die jeweiligen Kinder-Menüeinträge auf.
Problem
Das ganze wird dann kritisch wenn man +200 Kategorien hat und die Anzahl der Ebenen entsprechend gesetzt hat. Dann kann der initiale Request gerne 15-20 Sekunden dauern (je nach Setup und Subshops).
In meinem Use-Case geht es hier um 6-8 Subshops, teilweise mit Sprachshops und Kategorien zwischen 60 und 350. Ihr könnt euch vorstellen, dass hier schnell die Last nach oben geht.
Aber selbst wenn man nur einen Shop hat, aber viele Kundengruppen, kann das ganze schnell frustrierend für den Kunden werden. Denn die Iteration an sich dauert einfach SEHR lange. Dafür wurde auch mal der Cache angelegt.
Cache
Das Caching erfolgt in der Bootstrap.php des Plugins AdvancedMenu unter
engine/Shopware/Plugins/Default/Frontend/AdvancedMenu/Bootstrap.php
in der getAdvancedMenu() Methode. Der Cache Key wird dabei mit
$cacheKey = 'Shopware_AdvancedMenu_Tree_' . $context->getShop()->getId() . '_' . $category . '_' . Shopware()->System()->sUSERGROUPDATA['id'];
generiert. Das ganze wird im APCU Cache abgelegt. Ich habe mir vorher einen Wolf im File-Cache und im Redis Cache gesucht. Aber schauen wir doch mal wie das im APCU aussieht
Wie Ihr hier seht und oben auch schon im Code steht – hier wird für jede Kundengruppe ein neuer Cache angelegt. Grundsätzlich ja ein nobler Ansatz, da ja versch. KG auch versch. Menüeinträge haben können oder eben auch nicht. Nur ist in unserem Fall das bei genau einem Shop der Fall, der Rest läuft zu 100% synchron mit der EK Kundengruppe.
Lösung
Die Lösung ist hier für uns sehr simpel. Wir haben einfach
Shopware()->System()->sUSERGROUPDATA['id']
aus dem Cache Key entfernt. Quick and dirty, aber sehr effizient! Damit wird das Menü nur einmal pro Shop angelegt und gilt für alle Kundengruppen – außerdem könnt Ihr je nach Bedarf dann noch den Cache auf 24h setzen. Besonders bei vielen Kundengruppen sind dabei oft Händler dabei, welche einen hohen Warenkorb haben und sicher nicht immer 20-30 Sekunden warten bis der convertCategoryStruct durchgelaufen ist.
Shopware
Hier wäre eine Lösung für ein Großteil der Kunden eine Plugin-Konfiguration die es erlaubt die Kundengruppe nicht mit in den Cache-Key einzubeziehen oder mal die convertCategoryStruct() anzupassen oder eine weitere Methode zu implementieren die einfach nur den Namen/Link der Kategorie zurückgibt – mehr ist nicht nötig.
Hallo,
danke für den Tipp. WIr haben seit einiger Zeit das problem das Kategorien (Aber nur Kategorien) bis zu 20 Sekunden laden.
Wo genau entferne ich en Eintrag im Cache Key? Wie gelande ich dort hin?
Vielen Dank für Ihre Antwort.
Hi Fabian,
ich vermute hier nicht das es das Menu ist, sondern etwas anderes.
Das Topmenu ist schon generiert (auch ohne Login ist jede Category langsam -> TTFB also irgendwas in PHP oder Mysql). Sprich da ist vermutlich ein Plugin im Listing was sehr langsam ist oder deine Datenbank/Server ist extrem langsam. Da Detail und der Rest aber schnell ist – vermute ich als erstes ein Plugin was im Listing etwas macht. Hast du einen Profiler? Tideways, Blackfire.io , New Relic? Da kannst du mal reinschauen. Bei wem hostest du? Kannst dich auch gerne per Mail bei mir melden, kann mir das für kleines Geld anschauen.
VG
Micha