ESI-Tag auf "externe" URL -oder- lightweight Shopware-Controller

Hallo zusammen,

folgende Situation: wir wollen im Shop ein Tracking-System serverseitig einbinden, weil die clientseitige Anbindung anfällig dafür ist, z.B. von Werbeblockern blockiert zu werden.

Damit das funktioniert, darf das Tracking-Skript selbst nicht gecached werden, während die Artikeldetailseite weiterhin gecached werden soll. Deshalb wollte ich das Tracking-Skript als action/Esi-Tag einfügen. Was soweit auch klappt, sprich ich hab mir eine Controller-Action geschrieben, die das Tracking-Skript enthält, und dieses per action-Tag eingebunden. Die Atikeldetailseite kommt aus dem Cache + das Tracking wird jedes Mal korrekt ausgeführt.

ABER : Natürlich lädt die Artikeldetailseite jetzt nicht mehr in 50ms, sondern in 500ms, weil ja noch der Request aus dem ESI-Tag vorher ausgeführt werden muss. Der shop enthält leider seeeehr viele Plugins, weshalb ein großer Overhead da ist und selbst ein simpler Controller-Request eben 500ms dauert.

So, da wir fürs Tracking jedoch weder Shopware-Funktionalität benötigen noch eine Datenbankverbindung oder sonstiges brauchen, wollte ich ein eigenes kleines PHP-Skript schreiben, was ich dann per ESI-Tag einbinde. Das PHP-Skript funktioniert soweit und lädt deutlich schneller (~100ms, eben solange wie der Request an die Cloud-Tracking-Software benötigt). Aber ich bekomme es nicht als ESI-Tag eingebunden!

An der Stelle, wo es eingebunden werden sollte, wird immer die gesamte Shopseite eingebunden, rekursiv, immer und immer wieder, bis der Browser abstürzt. In de rBootstrap des HttpCache Plugins wird das ESI-Tag mit

return '';

gebildet. $url ist hier jedoch keine vollständige URL, sondern ein String im Format /?controller=xyz&action=abc usw. Wenn ich an dieser Stelle den gleichen absoluten Link einfüge, also z.B. shopurl.de/xyz/abc dann funktioniert es nicht mehr und die Seite wird wieder rekursiv aufgerufen.

Frage: Wie schaffe ich es, eine „externe“ URL per Esi-Tag einzubinden, also eine URL, die KEIN Shopware-Controller ist?

 - oder -

Gibt es irgendeine Art „lightweight“-Showpare-Controller, der zwar über die Standard-Konventionen gebildet wird, aber keinerlei Overhead (Pre, Post-Dispatch etc.) hat?

Viele Grüße
Malte :slight_smile:

Uhh spannend. Sowas hab ich auch schonmal versucht und bin nicht weiter gekommen. Wenn jemand ne Lösung hat, würde ich die auch nehmen :wink: Ich brauch nämlich an einer Stelle den HTTP_REFERER Header. Aber dafür einmal Showpare booten ist totaler Overkill.

Hi,

über einen ESI-Tag ist das mMn nicht so ohne Weiteres möglich, da gibt es ja drei verschiedene Szenarien, die berücksichtigt werden müssen:

  • Kein Cache: Shopware löst Action-Tags über einen internen Dispatch auf - keine Instanz löst ESI-Tags auf
  • Symfony-Cache: ESI-Tags werden über eine Abkürzung im Kernel ebenfalls über den internen Dispatch-Loop aufgelöst
  • Varnish: ESI-Tags werden extern an den Shopware-Kernel übergeben und wie eigene Requests gehandhabt

Hinzu kommt das Problem, dass ESI-Tags ja in der Regel auch synchron aufgelöst werden, d.h. die Seite wird dadurch ja per se nicht schneller. Meines Wissens ist nur Varnish in der Pro-Version in der Lage, ESI-Tags asynchron aufzulösen. Selbst wenn du es also über ESI-Tags implementieren könntest, hättest du dadurch in den meisten Fällen keinen Geschwindigkeitsvorteil. Das habe ich hier mal zusammengefasst: On action tags vgl. dazu auch diese Animation:

Wenn es dir nur um generelle Adblock-Regeln geht, wäre es ja eigentlich schon zielführend, wenn du einfach einen Shopware-Controller mit unverfänglichem Namen implementierst und darin dann serverseitig den Tracking-Service aufrufst. Nutzer könnten dann zwar weiterhin individuell diesen Ajax-Call blocken - aber es ist ja relativ unwahrscheinlich, dass diese konkrete URL deines Shops Einzug in eine Adblock-Liste erhält, oder? Alternativ könntest du dich auch an einen Standard-Ajax-Call von SW hängen, „refreshStatistics“ beispielsweise.

„lightweight Controller“ gibt es in der Form nicht - der „widget“ Namespace hat in der Hinsicht ein paar Besonderheiten und war mal so angedacht - aber unterm Strich ist der Stack dort nicht nennenswert kleiner, als der Stack bei den anderen Controller-Namespaces. 

Eine ganz generelle Lösung ohne Ajax und Iframe und ohne Manipulationen an der shopware.php fällt mir da also so auf die Schnelle nicht ein.

Besten Gruß

Daniel

1 Like

Hi Daniel,

danke für die ausführliche Antwort!

Den Geschwindigkeitsvorteil erhoffe ich mir insofern, weil die Artikeldetailseite ungecached >5-10 Sekunden lädt, je nachdem, ob Proxydateien etc. schon angelegt wurden oder nicht. Sprich durch den ESI-Tag mit einem normalen Shopware-Controller habe ich schon einen immensen Geschwindigkeitsvorteil gegenüber der Lösung, dass die Artikeldetailseite einfach gar nicht mehr gecached wird (Größenverhältnis ungecached 5s, Cache + ESI 500ms, Cache ohne ESI 50ms, aber dann funktioniert das Tracking halt nicht mehr ;D ). Hatte halt gehofft, dass es irgendwie noch eine schnellere Methode als den Shopware-Controller gibt. Was mir aber gerade noch einfällt, ich hab jetzt einen Frontend-Controller benutzt, ich sollte es eventuell mal mit einem Widget-Controller probieren!

An die Idee mit Ajax hatte ich auch schon gedacht, allerdings möchte unser Kunde gerne komplett auf JavaScript beim Tracking verzichten, weil er es „lückenlos“ haben möchte. Kann man serverseitig natürlich auch nicht 100% garantieren, aber naja… müssen jetzt mal Vor- und Nachteile abwegen von Geschwindigkeit und eventuellem Datenverlust, wenn man’s nicht komplett serverseitig macht.

Danke jedenfalls erstmal für die Rückmeldung!

Viele Grüße
Malte :slight_smile: