سائٹ کے روٹ لے آؤٹ (root layout) میں موجود ایک مشترکہ فنکشن نے A/B ٹیسٹ کے ایکسپوزر کاؤنٹر (exposure counter) کو پیج ویو کاؤنٹر (page-view counter) میں تبدیل کر دیا، جس سے سیمپل سائز بڑھ گیا اور کنورژن ریٹس (conversion rates) بے معنی ہو گئے۔ ہوم پیج کے 50/50 تقسیم والے اس ٹیسٹ میں، ایک ویریئنٹ کے لیے 178 ہٹس اور دوسرے کے لیے 57 ہٹس رپورٹ ہوئیں—جو کہ متوقع برابر تقسیم سے بہت دور تھیں۔
یہ غلطی رینڈمائزر (randomizer) سے کیسے بچ نکلی
ڈویلپر نے سب سے پہلے اس رینڈمائزر کی تصدیق کی جو وزٹرز کو کسی ویریئنٹ کے لیے مختص کرتا ہے۔ اس نے مڈل ویئر (middleware) کا مطالعہ کیا، کوکی لاجک (cookie logic) کا معائنہ کیا اور ایک اسکرپٹ چلایا جس نے اسائنمنٹ فنکشن کو 10,000 بار کال کیا؛ اس نے بالکل درست 50/50 تقسیم فراہم کی۔ رینڈمائزر خود درست کام کر رہا تھا؛ مسئلہ یہ تھا کہ ایکسپوزر (exposure) کو کیسے ریکارڈ کیا جا رہا تھا۔
ایک ہی فنکشن دو کام انجام دے رہا تھا:
- ویریئنٹ سیٹ کرنا (Set the variant) – وزٹر کے تجربے کو مستقل مزاج رکھنے کے لیے ہر پیج لوڈ پر چلتا ہے۔
- ایکسپوزر ایونٹ ریکارڈ کرنا (Record the exposure event) – یہ صرف ایک وزٹر کے لیے ایک بار، اس لمحے چلنا چاہیے جب ویریئنٹ پہلی بار نظر آئے۔
یہ فنکشن روٹ لے آؤٹ (root layout) میں موجود تھا، جو ہر نیویگیشن پر رینڈر (render) ہونے والا ایک کمپوننٹ ہے۔ چونکہ ایکسپوزر ریکارڈ کرنے والا کوڈ ہر بار لے آؤٹ کے رینڈر ہونے پر چلتا تھا، اس لیے ہر پیج ویو کو ایک نیا ایکسپوزر سمجھا گیا۔ ہوم پیج کے دونوں ویریئنٹ مختلف لے آؤٹ ٹریز (layout trees) استعمال کر رہے تھے، اس لیے ان کے پیج ویو ریٹس میں فرق آگیا، جس سے ایسا لگا جیسے رینڈمائزر خراب ہو گیا ہے۔
غلط گنتی کیوں اہم تھی
کنورژن کے اعداد و شمار—جیسے کلک تھرو، سائن اپ، اور خریداری—درست طور پر لاگ (log) کیے گئے تھے۔ لیکن ڈینومینیٹر (denominator - ایکسپوزرز کی تعداد) غلط تھا۔ حساب شدہ کنورژن ریٹس حقیقت سے بہت کم نظر آئے، اور ان ریٹس کی بنیاد پر کیے گئے کوئی بھی فیصلے ناقابل اعتبار تھے۔
اس فرق کے سامنے آنے سے پہلے ٹیسٹ دو ہفتوں تک چلتا رہا، جس کی وجہ سے ٹیم کو پورا ڈیٹا سیٹ ضائع کرنا پڑا۔
حل
حل سادہ تھا: ذمہ داریوں کو الگ الگ فنکشنز میں تقسیم کر دیا گیا۔ ایکسپوزر ریکارڈ کرنے والا کوڈ اب چیک کرتا ہے کہ آیا وزٹر کو پہلے ہی گنا جا چکا ہے یا نہیں، اور یہ صرف ایک صارف کے لیے ایک بار چلتا ہے۔ ویریئنٹ سیٹ کرنے والا کوڈ اپنی جگہ پر برقرار ہے اور ہر نیویگیشن پر چلتا رہتا ہے۔
تجربات کرنے والوں کے لیے تین اہم نکات
- اسٹیٹ سیٹنگ (state-setting) کو ون آف ایونٹس (one-off events) سے الگ رکھیں۔ ایسا فنکشن جو ویریئنٹ بھی مختص کرے اور ایکسپوزر بھی لاگ کرے، وہ ٹکرا جائے گا کیونکہ پہلا بار بار چلتا ہے جبکہ دوسرے کو نہیں چلنا چاہیے۔
- روٹ لے آؤٹ میں ون شاٹ لاجک (one-shot logic) سے بچیں۔ کسی بھی ایسے کمپوننٹ میں رکھی گئی چیز جو ہر پیج لوڈ پر رینڈر ہوتا ہے، وہ بار بار چلے گی، جس سے "ایک وزٹر کے لیے ایک بار" کا عمل "ایک پیج ویو کے لیے ایک بار" میں بدل جائے گا۔
- جب مشاہدہ شدہ تقسیم (observed split) رینڈمائزر کے برعکس ہو، تو پہلے کاؤنٹر کا آڈٹ کریں۔ ڈویلپرز اکثر رینڈمائزر کی شفافیت کو چیک کرتے ہیں لیکن شاذ و نادر ہی اس بات کی تصدیق کرتے ہیں کہ گنتی کا طریقہ کار درست ہے۔
آگے کس چیز کا خیال رکھیں
کوئی بھی تجربہ جو ایکسپوزر کے لیے ایک ہی کاؤنٹر پر انحصار کرتا ہے، اس کا آڈٹ کیا جانا چاہیے کہ وہ کاؤنٹر کمپوننٹ ٹری (component tree) میں کہاں واقع ہے۔ اگر کاؤنٹر کسی گلوبل لے آؤٹ (global layout) میں ہے، تو ایک ایسا چیک شامل کریں جو اس ایونٹ کو کسی مستقل شناسنما (persistent identifier)—جیسے کہ کوکی یا لوکل اسٹوریج فلیگ (local-storage flag)—کے ساتھ جوڑ دے۔ ٹیموں کو اپنے ڈیش بورڈز میں ایک سینٹی چیک (sanity check) بھی شامل کرنا چاہیے: اگر مشاہدہ شدہ ویریئنٹ کی تقسیم ایک معمولی شماریاتی حد سے زیادہ مختلف ہو، تو رینڈمائزر کے خراب ہونے کا اندازہ لگانے سے پہلے کاؤنٹر کے آڈٹ کے لیے ٹیسٹ کو فلیگ کریں۔
مختصراً یہ کہ، ایک قابل اعتماد ایکسپوزر کاؤنٹ کے بغیر ایک بہترین کام کرنے والا رینڈمائزر بھی بے کار ہے۔ ذمہ داریوں کو تقسیم کرنا اور ون آف ایونٹس کو ہمیشہ رینڈر ہونے والے کمپوننٹس سے باہر رکھنا A/B ٹیسٹ کو درست رکھتا ہے اور ہفتوں کی ضائع شدہ تجزیہ کاری سے بچاتا ہے۔
