Une fonction partagée dans le layout racine du site a transformé un compteur d'exposition de test A/B en un compteur de vues de pages, gonflant la taille de l'échantillon et rendant les taux de conversion insignifiants. Le test, une répartition 50/50 de la page d'accueil, a rapporté 178 hits pour une variante et 57 pour l'autre — bien loin de la répartition équitable attendue.

Comment l'erreur a échappé au randomiseur

Le développeur a d'abord vérifié le randomiseur qui assigne les visiteurs à une variante. Il a lu le middleware, inspecté la logique des cookies et exécuté un script qui appelait la fonction d'assignation 10 000 fois ; il a produit une répartition parfaite de 50/50. Le randomiseur lui-même fonctionnait ; le problème résidait dans la manière dont l'exposition était enregistrée.

Une seule fonction effectuait deux tâches :

  1. Définir la variante – s'exécute à chaque chargement de page pour maintenir la cohérence de l'expérience du visiteur.
  2. Enregistrer l'événement d'exposition – ne devrait se déclencher qu'une seule fois par visiteur, au moment où la variante apparaît pour la première fois.

La fonction se trouvait dans le layout racine, un composant rendu à chaque navigation. Comme le code d'enregistrement de l'exposition s'exécutait à chaque rendu du layout, chaque vue de page comptait comme une nouvelle exposition. Les deux variantes de la page d'accueil utilisaient des arbres de layout légèrement différents, de sorte que leurs taux de vues de pages divergeaient, créant l'illusion d'un randomiseur défaillant.

Pourquoi cette erreur de comptage était importante

Les chiffres de conversion — clics, inscriptions, achats — étaient enregistrés correctement. Mais le dénominateur (le nombre d'expositions) était erroné. Les taux de conversion calculés semblaient bien inférieurs à la réalité, et toute décision basée sur ces taux était peu fiable.

Le test a fonctionné pendant deux semaines avant que l'écart ne soit détecté, forçant l'équipe à rejeter l'ensemble du jeu de données.

La solution

La solution était simple : séparer les responsabilités en fonctions distinctes. Le code d'enregistrement de l'exposition vérifie désormais si le visiteur a déjà été comptabilisé, ne se déclenchant qu'une seule fois par utilisateur. Le code de définition de la variante reste là où il est, continuant de s'exécuter à chaque navigation.

Trois enseignements pour quiconque mène des expérimentations

  • Séparez la définition de l'état des événements ponctuels. Une fonction qui assigne à la fois une variante et enregistre une exposition entrera en conflit, car la première se répète alors que la seconde ne le doit pas.
  • Évitez la logique ponctuelle dans un layout racine. Tout ce qui est placé dans un composant rendu à chaque chargement de page s'exécutera de manière répétée, transformant le « une fois par visiteur » en « une fois par vue de page ».
  • Lorsque la répartition observée contredit le randomiseur, auditez d'abord le compteur. Les développeurs testent souvent l'équité du randomiseur, mais vérifient rarement que le mécanisme de comptage est précis.

Ce qu'il faut surveiller par la suite

Toute expérimentation reposant sur un compteur unique pour l'exposition devrait faire l'objet d'un audit pour déterminer où ce compteur se situe dans l'arbre des composants. Si le compteur se trouve dans un layout global, ajoutez une vérification qui lie l'événement à un identifiant persistant — tel qu'un cookie ou un flag dans le local-storage. Les équipes devraient également intégrer un test de cohérence dans leurs tableaux de bord : si la distribution observée des variantes s'écarte au-delà d'une faible marge statistique, signalez le test pour un audit du compteur avant de supposer que le randomiseur est défaillant.

En résumé, un randomiseur qui fonctionne bien est inutile sans un comptage d'exposition fiable. Séparer les responsabilités et placer les événements ponctuels en dehors des composants rendus en permanence garantit l'intégrité des tests A/B et évite des semaines d'analyses inutiles.