تسببت دالة مشتركة في التخطيط الجذري (root layout) للموقع في تحويل عداد التعرض لاختبار A/B إلى عداد لمشاهدات الصفحة، مما أدى إلى تضخيم حجم العينة وجعل معدلات التحويل بلا معنى. أظهر الاختبار، الذي كان يعتمد تقسيمًا بنسبة 50/50 للصفحة الرئيسية، 178 زيارة لأحد المتغيرات و57 للآخر — وهو ما يبتعد تمامًا عن التقسيم المتساوي المتوقع.
كيف أفلت الخطأ من أداة التوزيع العشوائي (randomizer)
تحقق المطور أولاً من أداة التوزيع العشوائي التي تخصص الزوار لمتغير معين. قام بمراجعة البرمجيات الوسيطة (middleware)، وفحص منطق ملفات تعريف الارتباط (cookie logic)، وشغل نصًا برمجيًا استدعى دالة التعيين 10,000 مرة؛ فنتج عن ذلك تقسيم مثالي بنسبة 50/50. كانت أداة التوزيع العشوائي تعمل بشكل صحيح؛ المشكلة كانت في كيفية تسجيل التعرض.
قامت دالة واحدة بمهمتين:
- تحديد المتغير – تعمل عند كل تحميل للصفحة للحفاظ على اتساق تجربة الزائر.
- تسجيل حدث التعرض – يجب أن يتم تشغيله مرة واحدة فقط لكل زائر، في اللحظة التي يظهر فيها المتغير لأول مرة.
كانت الدالة موجودة في التخطيط الجذري (root layout)، وهو مكون يتم عرضه (rendered) عند كل عملية تنقل. ولأن كود تسجيل التعرض كان يُنفذ في كل مرة يتم فيها عرض التخطيط، فقد تم احتساب كل مشاهدة صفحة على أنها تعرض جديد. استخدم المتغيران في الصفحة الرئيسية أشجار تخطيط (layout trees) مختلفة قليلاً، لذا تباينت معدلات مشاهدة الصفحة لكل منهما، مما خلق وهمًا بأن أداة التوزيع العشوائي معطلة.
لماذا كان الخطأ في العد مهمًا
تم تسجيل أرقام التحويل — مثل النقر، والتسجيل، وعمليات الشراء — بشكل صحيح. لكن المقام (عدد مرات التعرض) كان خاطئًا. بدت معدلات التحويل المحسوبة أقل بكثير من الواقع، وكانت أي قرارات تُبنى على تلك المعدلات غير موثوقة.
استمر الاختبار لمدة أسبوعين قبل أن يظهر هذا التباين، مما أجبر الفريق على التخلص من مجموعة البيانات بأكملها.
الإصلاح
كان الحل مباشرًا: تقسيم المسؤوليات إلى دوال منفصلة. أصبح كود تسجيل التعرض يتحقق الآن مما إذا كان الزائر قد تم عده بالفعل، بحيث يتم تشغيله مرة واحدة فقط لكل مستخدم. أما كود تحديد المتغير فبقي في مكانه، مستمرًا في العمل عند كل عملية تنقل.
ثلاث نصائح لأي شخص يدير تجارب
- افصل بين تعيين الحالة والأحداث التي تحدث لمرة واحدة. الدالة التي تقوم بتعيين متغير وتسجيل التعرض في آن واحد ستتعارض، لأن الأولى تتكرر بينما يجب ألا تتكرر الثانية.
- تجنب المنطق الذي يعمل لمرة واحدة (one-shot logic) في التخطيط الجذري. أي شيء يوضع في مكون يتم عرضه عند كل تحميل للصفحة سيُنفذ بشكل متكرر، مما يحول "مرة واحدة لكل زائر" إلى "مرة واحدة لكل مشاهدة صفحة".
- عندما يتعارض التقسيم الملحوظ مع أداة التوزيع العشوائي، راجع العداد أولاً. غالبًا ما يختبر المطورون عدالة أداة التوزيع العشوائي، لكنهم نادرًا ما يتحققون من دقة آلية العد.
ما يجب مراقبته لاحقًا
يجب مراجعة أي تجربة تعتمد على عداد واحد للتعرض لمعرفة مكان وجود هذا العداد في شجرة المكونات (component tree). إذا كان العداد موجودًا في تخطيط عام (global layout)، فأضف تحققًا يربط الحدث بمعرف مستمر — مثل ملف تعريف ارتباط (cookie) أو علامة في التخزين المحلي (local-storage flag). كما يجب على الفرق بناء فحص منطقي (sanity check) في لوحات التحكم الخاصة بهم: إذا انحرف توزيع المتغيرات الملحوظ عن هامش إحصائي صغير، فقم بتمييز الاختبار لإجراء مراجعة للعداد قبل افتراض أن أداة التوزيع العشوائي معطلة.
باختصار، أداة التوزيع العشوائي التي تعمل بشكل جيد لا فائدة منها بدون عداد تعرض موثوق. إن تقسيم المسؤوليات ووضع الأحداث التي تحدث لمرة واحدة خارج المكونات التي يتم عرضها دائمًا يحافظ على نزاهة اختبارات A/B ويوفر أسابيع من التحليلات الضائعة.
