Eine gemeinsam genutzte Funktion im Root-Layout der Website verwandelte einen Expositions-Zähler für A/B-Tests in einen Seitenaufruf-Zähler, was die Stichprobengröße aufblähte und die Konversionsraten bedeutungslos machte. Der Test, ein 50/50-Split der Homepage, meldete 178 Treffer für eine Variante und 57 für die andere – weit entfernt von der erwarteten gleichmäßigen Verteilung.

Wie der Fehler am Randomizer vorbeigeschlüpft ist

Der Entwickler überprüfte zunächst den Randomizer, der die Besucher einer Variante zuweist. Er las die Middleware, untersuchte die Cookie-Logik und führte ein Skript aus, das die Zuweisungsfunktion 10.000 Mal aufrief; es ergab einen perfekten 50/50-Split. Der Randomizer selbst funktionierte; das Problem war die Art und Weise, wie die Exposition aufgezeichnet wurde.

Eine einzige Funktion übernahm zwei Aufgaben:

  1. Die Variante festlegen – wird bei jedem Seitenaufruf ausgeführt, um ein konsistentes Nutzererlebnis zu gewährleisten.
  2. Das Exposure-Event aufzeichnen – sollte nur einmal pro Besucher ausgelöst werden, in dem Moment, in dem die Variante zum ersten Mal erscheint.

Die Funktion befand sich im Root-Layout, einer Komponente, die bei jeder Navigation gerendert wird. Da der Code zur Aufzeichnung der Exposition jedes Mal ausgeführt wurde, wenn das Layout gerendert wurde, zählte jeder Seitenaufruf als neue Exposition. Die beiden Homepage-Varianten verwendeten leicht unterschiedliche Layout-Bäume, weshalb ihre Seitenaufruf-Raten auseinandergingen, was die Illusion eines defekten Randomizers erzeugte.

Warum die Fehlzählung wichtig war

Die Konversionszahlen – Click-Throughs, Anmeldungen, Käufe – wurden korrekt protokolliert. Aber der Nenner (die Anzahl der Expositionen) war falsch. Die berechneten Konversionsraten erschienen weitaus niedriger als die Realität, und alle auf diesen Raten basierenden Entscheidungen waren unzuverlässig.

Der Test lief zwei Wochen lang, bevor die Diskrepanz auftauchte, was das Team zwang, den gesamten Datensatz zu verwerfen.

Die Lösung

Die Lösung war einfach: Die Verantwortlichkeiten wurden in separate Funktionen aufgeteilt. Der Code zur Aufzeichnung der Exposition prüft nun, ob der Besucher bereits gezählt wurde, und wird nur noch einmal pro Nutzer ausgelöst. Der Code zur Festlegung der Variante bleibt dort, wo er ist, und wird weiterhin bei jeder Navigation ausgeführt.

Drei Erkenntnisse für alle, die Experimente durchführen

  • Trennen Sie die Zustandssetzung von einmaligen Ereignissen. Eine Funktion, die sowohl eine Variante zuweist als auch eine Exposition protokolliert, wird kollidieren, da Erstere wiederholt wird, Letztere hingegen nicht.
  • Vermeiden Sie One-Shot-Logik in einem Root-Layout. Alles, was in einer Komponente platziert wird, die bei jedem Seitenaufruf gerendert wird, wird wiederholt ausgeführt, wodurch aus „einmal pro Besucher“ „einmal pro Seitenaufruf“ wird.
  • Wenn der beobachtete Split dem Randomizer widerspricht, prüfen Sie zuerst den Zähler. Entwickler testen oft die Fairness des Randomizers, verifizieren aber selten, ob der Zählmechanismus korrekt arbeitet.

Worauf man als Nächstes achten sollte

Jedes Experiment, das sich auf einen einzelnen Zähler für die Exposition verlässt, sollte daraufhin überprüft werden, wo dieser Zähler im Komponentenbaum angesiedelt ist. Wenn der Zähler in einem globalen Layout liegt, fügen Sie eine Prüfung hinzu, die das Ereignis an eine persistente Kennung bindet – wie etwa ein Cookie oder ein Local-Storage-Flag. Teams sollten zudem einen Sanity-Check in ihre Dashboards einbauen: Wenn die beobachtete Variantenverteilung über eine kleine statistische Fehlermarge hinaus abweicht, sollte der Test für eine Zählerprüfung markiert werden, bevor man davon ausgeht, dass der Randomizer defekt ist.

Kurz gesagt: Ein gut funktionierender Randomizer ist nutzlos ohne eine vertrauenswürdige Zählung der Expositionen. Die Trennung von Verantwortlichkeiten und das Platzieren von einmaligen Ereignissen außerhalb von Komponenten, die ständig gerendert werden, sorgt für ehrliche A/B-Tests und erspart wochenlange, verschwendete Analysen.