TL;DR siehe unten.
Wir haben seit Wochen starke Performance Probleme (seit Upgrade auf 5.6.4) und waren schon am verzweifeln. Heute habe ich erneut xdebug angeworfen um mich abermals in die Untiefen von shopware zu stürzen. Vorab eine kurze Analyse des ist-Zustandes.
Je mehr Artikel in einer Kategorie oder Suche, desto langsamer der Seitenaufbau. Und damit meine ich wirklich ob 100 oder 1.000 (angezeigt werden jeweilse nur 48). Sprich es hatte nur indirekt mit der Anzahl zu tun. Der Seitenaufbau war bei 1.000 Artikeln dann schon bei ~3 Sekunden angekommen. Die Zeit wurde fast ausschließlich als CPU Zeit in PHP verbraten. strace war leider auch nicht hilfreich.
Alle Lösungsansätze hier im Forum hatten nicht geholfen bzw. ich hatte vermutlich nicht die richtigen Stellen gefunden. Auch das Changelog durchwühlen war ein herumstochern ohne Ergebnis. Im nachhinein habe ich einen Beitrag von Moritz Naczenski gefunden, der dies anspricht, dem Threadersteller aber nicht geholfen hatte und auch den entsprechenden Changelog Eintrag (zu 5.6.0).
Nun also die Erkenntnisse:
“HTML Komprimierung aktivieren” unter Performance > Einstellungen > Allgemein > Verschiedenes nutzt einen Regex (siehe https://issues.shopware.com/issues/SW-23199 bzw. engine/Shopware/Components/Template/HtmlMinCompressor.php), der von stackoverflow (https://stackoverflow.com/questions/5312349/minifying-final-html-output-using-regular-expressions-with-codeigniter) übernommen wurde und leider inperformant ist (in Sachen CPU-Usage).
Hier erst mal das Ergebnis:
Unkomprimiert:
-rw-r--r-- 1 root root 242192 Mar 12 18:33 index.minified.html
-rw-r--r-- 1 root root 950373 Mar 12 18:32 index.orig.html
Komprimiert:
-rw-r--r-- 1 root root 24170 Mar 12 18:33 index.minified.html.gz
-rw-r--r-- 1 root root 38295 Mar 12 18:32 index.orig.html.gz
Ich will gar nicht absprechen, dass das durchaus sinnvoll sein kann (wobei wir hier von 14k Differenz sprechen), ich finde nur fatal wie es umgesetzt wurde.
Ich habe ein Testskript erstellt, was nur den Inhalt via file_get_contents einliest, den Regex aus engine/Shopware/Components/Template/HtmlMinCompressor.php anwendet und per file_put_contents wieder speichert:
# time php HtmlMinCompressor.php
real 0m2.498s
user 0m2.468s
sys 0m0.012s
Danach habe ich einfach aus dem gleichen stackoverflow Beitrag weiter unten eine Funktion übernommen, die erst alle Einträge, die nicht minified werden dürfen, durch Platzhalter ersetzt, dann HTML minified und am Ende die Platzhalter wieder mit dem originalen Inhalt austauscht, eingebunden (die original Funktion aus dem Beitrag entfernt als erstes noch alle Kommentare, das habe ich nicht übernommen). Das Ergebnis ist bis auf einen abschließenden Zeilenumbruch identisch.
# time php HtmlMinCompressorOptimized.php
real 0m0.023s
user 0m0.016s
sys 0m0.004s
Soweit so gut. Jetzt habe ich noch schnell geschaut, wieso ich überhaupt 700.000 whitespaces in meiner Seite habe und bin über den Filter gestoßen (Grundeinstellungen > Storefront > Filter / Sortierung), der auf jeder Seite ist und bei uns immer alle Eigenschaften, die die Artikel haben, anbietet. Dieser wird immer umfangreicher, je mehr Artikel in einer Kategorie sind, weil dann immer mehr Optionen zu den Eigenschaften angeboten werden.
Hier ein Beispiel eines einzelnen Eintrags:
Streifen
Davon gibt es dann halt z.B. 328 Einträge auf einer Seite mit vielen Artikeln.
Vielleicht wäre es besser gewesen einen Template HTML Minifizierer zu erstellt, damit dies nur beim kompilieren passiert und nicht bei jedem Seitenaufruf. Dann wäre die schlechte Performance auch nicht fatal gewesen.
TL;DR
“HTML komprimieren” ist mittels inperformantem regex-only umgesetzt worden und sollte nicht genutzt werden (bis es hoffentlich schnellstmöglich gepatcht wird).