1const observer = new MutationObserver(mutations => {
2 mutations.forEach(mutation => {
3 if (mutation.addedNodes.length > 0) {
4 applyTestChanges();
5 }
6 });
7});
8
9observer.observe(document.getElementById('product-list'), { childList: true });
Conversion Rate Optimization/23. Januar 2024 -Aktualisiert am 28. September 2024/7 Min. Lesezeit
Technische Herausforderungen und Lösungen für A/B Tests in SPAs
Single-Page Applications (SPAs) bieten eine dynamische und reaktive Benutzererfahrung, stellen jedoch auch spezielle Herausforderungen für die Durchführung von A/B-Tests dar. In diesem Artikel fokussieren wir uns auf zwei spezifische technische Probleme und bieten Lösungsansätze, die für Entwickler in diesem Bereich relevant sind.
Hintergrund
A/B-Tests sind bei Single Page Applications (SPAs) unter Verwendung von Frameworks wie React.js, Angular und Vue.js eine Herausforderung. Diese Frameworks sind bei JavaScript-Entwicklern beliebt, da sie die Entwicklung ausgefeilter Benutzeroberflächen ermöglichen, was zu besseren Nutzererfahrungen und höheren Konversionsraten führt. Sie bieten Vorteile wie das Vermeiden von Seitenaktualisierung, schnellere Seitenladegeschwindigkeiten, flüssige Interaktionen, reduzierte Datentransfers und wiederverwendbare Komponenten, die eine schnellere Entwicklung ermöglichen. Allerdings haben sie einen bedeutenden Nachteil, aufgrund der Funktionsweise dieser Frameworks haben clientseitige A/B-Testing-Tools Schwierigkeiten, korrekt zu funktionieren.
Bei SPAs erfolgt das Browsen auf einer Webseite ohne die Notwendigkeit, die Seite einschließlich der URL neu zu laden. Der Status der Seite unterliegt dabei ständigen Änderungen durch jede Benutzerinteraktion. Da A/B-Testing-Tools üblicherweise nur Anpassungen während eines initialen Seitenaufruf vornehmen, bleiben nachfolgende Interaktionen unberücksichtigt. Die Funktionalität clientseitiger A/B-Testing-Software und Personalisierungsplattformen sind auf das vollständige Rendern einer Seite angewiesen. Da dieses Konzept bei der Verwendung von SPA-Frameworks wie React, Angular oder Vue fehlt, wird es schwieriger zu bestimmen, wann neuer Inhalt zur Seite hinzugefügt wurde oder sich der Status des bestehenden Inhalts geändert hat. A/B-Testing-Tools müssen also in der Lage sein, den Kontext des Users zu erkennen, beispielsweise, ob er sich auf einer Produktliste, Produktdetailseite oder im Warenkorb befindet und wann neuer Inhalt geliefert werden sollte. In Frameworks wie React.js führt jede Benutzerinteraktion dazu, dass ein oder mehrere UI-Elemente aktualisiert werden, was wiederum zur Löschung sämtlicher Änderungen führt, die durch die A/B-Testlösung vorgenommen wurden.
Problem 1: Überschreiben von Testanpassungen
Herausforderung
In SPAs können Änderungen, die durch A/B-Tests eingeführt werden, leicht überschrieben werden, wenn die SPA neue Inhalte lädt oder aktualisiert. Dies passiert, weil SPAs häufig DOM-Elemente neu rendern, was zu einem Verlust der durch den A/B-Test eingeführten Änderungen führen kann.
Lösung
MutationObserver
Einsatz von MutationObserver, um Änderungen im DOM zu überwachen und Testanpassungen durchzuführen, sobald relevante Elemente verfügbar sind. MutationObserver bieten eine umfassendere und detailliertere Schnittstelle für die Überwachung vieler verschiedener Arten von DOM-Änderungen, sind aber in Maßen komplex in der Einrichtung und Verwendung.
SentinelJS
Eine vereinfachte, benutzerfreundliche Methode zum Überwachen spezifischer Änderungen im DOM, insbesondere das Einfügen neuer Elemente, ist die SentinelJS Library.
SentinelJS verwendet dynamisch definierte CSS-Animationsregeln (@keyframes), um sich in Browser-Animation Startereignisse einzubinden, wenn ein neuer Knoten, der einem bestimmten CSS-Selektor entspricht, zum DOM hinzugefügt wird. Im Allgemeinen sollte dies leistungsfähiger sein als die Verwendung eines Mutation Observer, der den gesamten Dokumentbaum auf Änderungen überwacht und alle neuen untergeordneten Knoten rekursiv durchläuft.
Beispiel-Szenario
Angenommen, wir führen einen A/B-Test in einem Online-Shop-SPA durch, bei dem wir den "In den Warenkorb"-Button in einer anderen Farbe darstellen möchten. Wenn die Seite neue Produkte nachlädt, wird dieser Button jedoch wieder in der Standardfarbe angezeigt. Wir wollen überprüfen, ob neue Produkte geladen werden, und sicherstellen, dass der "In den Warenkorb"-Button die Farbe behält, die durch den A/B-Test festgelegt wurde.
Beispiel-Implementierung
MutationObserver
Sentinel-js
1import Sentinel from 'sentinel-js';
2Sentinel.on('product-added', applyTestChanges);
Erklärung
MutationObserver überwacht Änderungen im DOM (insbesondere das Hinzufügen neuer Produktknoten) und ruft applyTestChanges() auf, um die Farbänderung am "In den Warenkorb"-Button erneut anzuwenden. SentinelJS nutzt CSS-Animationsregeln, um das Hinzufügen neuer Produktknoten zu erfassen. Wenn ein neues Produkt hinzugefügt wird, wird applyTestChanges() aufgerufen.
Problem 2: Beibehalten von Testzuständen beim Navigieren
Herausforderung
In SPAs wird der Zustand oft nicht beim Vor- und Zurückgehen im Browser beibehalten. Dies kann dazu führen, dass Anpassungen, die durch A/B-Tests vorgenommen wurden, beim Navigieren im Browserhistorie nicht erneut geladen werden.
Lösungen
Datenattribute setzen
Dynamisch Datenattribute auf dem `body`-Element basierend auf der aktuellen URL zu setzen oder zu entfernen. Diese Funktion ist besonders nützlich in SPAs, wo die URL sich ändern kann, ohne dass die Seite neu geladen wird. Sie ermöglicht es, spezifische A/B-Tests auf bestimmte Seiten oder URLs zu beschränken und stellt sicher, dass die Ausspielung der A/B-Tests auf der richtigen Seite aktiv ist. Alternativ kann die History-API genutzt werden.
Browser History API
Um den Zustand der A/B-Testvarianten zu speichern, kann die History API des Browsers genutzt werden. Dadurch kann der entsprechende Zustand wiederhergestellt werden, wenn der User vor oder zurück navigiert.
Beispiel-Szenario: Online-Buchhandlung
Angenommen, wir betreiben eine Online-Buchhandlung als Single Page Application (SPA). Wir möchten einen A/B-Test durchführen, um zu sehen, ob eine Änderung im Layout der Buchdetails-Seite (z.B. die Positionierung der Buchbeschreibung und Bewertungen) die Benutzerinteraktion verbessert.
Wenn ein User über die Browser-Navigation vor- und zurückgeht, geht der Zustand des A/B-Tests verloren. Beispielsweise könnte ein User, der die geänderte Layout-Version der Buchdetails-Seite gesehen hat, beim Zurückkehren zur Hauptseite und erneutem Öffnen eines Buches das ursprüngliche Layout sehen.
Beispiel-Implementierung
Datenattribute setzen
1export default function setPageType(pages) {
2 function updatePageType() {
3 const body = document.body;
4 pages.forEach(page => {
5 const attr = `data-pp-${Object.keys(page)[0]}`;
6 const urlValue = Object.values(page)[0];
7 const hasUrl = urlValue instanceof RegExp ? urlValue.test(window.location.href) : window.location.href.includes(urlValue);
8 body[hasUrl ? 'setAttribute' : 'removeAttribute'](attr, '');
9 });
10 }
11
12 // Event-Handler für URL-Änderungen hinzufügen
13 window.addEventListener('popstate', updatePageType);
14 window.addEventListener('load', updatePageType);
15
16 // Initialen Aufruf der Funktion
17 updatePageType();
18}
19
20// Beispiel-Aufruf
21setPageType([{ 'home': '/home' }, { 'about': '/about' }]);
Erklärung
Die Funktion updatePageType überprüft die aktuelle URL und setzt oder entfernt entsprechend Datenattribute im body-Element.mEvent-Listener für popstate und load werden hinzugefügt, um auf Änderungen in der Browser-Navigation und beim Laden der Seite zu reagieren. Die Funktion wird beim Initialisieren und bei entsprechenden Events aufgerufen, um sicherzustellen, dass die Datenattribute immer korrekt gesetzt sind.
Fazit
Die Durchführung von A/B-Tests in Single-Page Applications (SPAs) ist aufgrund der Dynamik und der Art, wie diese Frameworks funktionieren, eine technische Herausforderung. Hervorzuheben sind dabei besonders zwei Hauptprobleme:
- Überschreiben von Testanpassungen: In SPAs können Änderungen, die durch A/B-Tests eingeführt wurden, leicht verloren gehen, wenn die SPA neue Inhalte lädt oder aktualisiert. Lösungsansätze wie der Einsatz von MutationObserver und SentinelJS bieten effektive Wege, um solche Probleme zu bewältigen. Während MutationObserver Änderungen im DOM überwacht und darauf reagiert, nutzt SentinelJS CSS-Animationsregeln, um auf das Hinzufügen neuer Elemente zu reagieren. Beide Methoden erfordern ein sorgfältiges Setup, um sicherzustellen, dass die durch A/B-Tests eingeführten Änderungen beibehalten werden.
- Beibehalten von Testzuständen beim Navigieren: Das zweite Hauptproblem besteht darin, dass in SPAs der Zustand oft nicht beim Vor- und Zurückgehen im Browser beibehalten wird. Lösungen wie das Setzen von Datenattributen auf dem Body-Element oder die Nutzung der Browser History API helfen dabei, den Zustand der A/B-Testvarianten zu speichern und bei der Navigation wiederherzustellen.
Zusammenfassend lässt sich sagen, dass A/B-Tests in SPAs durchaus machbar sind, aber spezielle Techniken und Werkzeuge erfordern, um die einzigartigen Herausforderungen zu bewältigen. Entwickler müssen sich mit fortgeschrittenen JavaScript-Konzepten und -Werkzeugen vertraut machen, um effektive und zuverlässige A/B-Tests in diesem Umfeld durchführen zu können. Die Nutzung von MutationObserver, SentinelJS und der History API sind nur einige der Ansätze, die dabei helfen können, diese Herausforderungen zu meistern.