సైట్లోని రూట్ లేఅవుట్లో (root layout) ఉన్న ఒక షేర్డ్ ఫంక్షన్, A/B-టెస్ట్ ఎక్స్పోజర్ కౌంటర్ను పేజీ-వ్యూ కౌంటర్గా మార్చేసింది. దీనివల్ల శాంపిల్ సైజ్ (sample size) పెరిగిపోయి, కన్వర్షన్ రేట్లు (conversion rates) అర్థరహితంగా మారాయి. హోమ్పేజీకి 50/50 స్ప్లిట్ చేసిన ఈ టెస్ట్లో, ఒక వేరియంట్కు 178 హిట్లు, మరొక వేరియంట్కు 57 హిట్లు నమోదయ్యాయి—ఇది ఆశించిన సమాన విభజన కంటే చాలా భిన్నంగా ఉంది.
ఈ లోపం రాండమైజర్ను (randomizer) ఎలా తప్పించుకుంది
డెవలపర్ మొదట సందర్శకులను ఒక వేరియంట్కు కేటాయించే రాండమైజర్ను తనిఖీ చేశారు. ఆయన మిడిల్వేర్ను (middleware) చదివి, కుక్కీ లాజిక్ను పరిశీలించి, అసైన్మెంట్ ఫంక్షన్ను 10,000 సార్లు పిలిచే స్క్రిప్ట్ను రన్ చేశారు; అది ఖచ్చితమైన 50/50 స్ప్లిట్ను ఇచ్చింది. రాండమైజర్ సరిగ్గానే పనిచేసింది; సమస్య ఎక్స్పోజర్ (exposure) ఎలా రికార్డ్ చేయబడుతుందనే దానిలో ఉంది.
ఒకే ఫంక్షన్ రెండు పనులను చేస్తోంది:
- వేరియంట్ను సెట్ చేయడం (Set the variant) – సందర్శకుడి అనుభవం స్థిరంగా ఉండటానికి ప్రతి పేజీ లోడ్ అయినప్పుడు ఇది రన్ అవుతుంది.
- ఎక్స్పోజర్ ఈవెంట్ను రికార్డ్ చేయడం (Record the exposure event) – వేరియంట్ మొదటిసారి కనిపించిన క్షణంలో, ప్రతి సందర్శకుడికి ఒకే ఒక్కసారి మాత్రమే ఇది జరగాలి.
ఆ ఫంక్షన్ రూట్ లేఅవుట్లో ఉంది, ఇది ప్రతి నావిగేషన్ (navigation) సమయంలో రెండర్ అయ్యే ఒక కాంపోనెంట్. ఎక్స్పోజర్-రికార్డింగ్ కోడ్ ప్రతిసారీ లేఅవుట్ రెండర్ అయినప్పుడు ఎగ్జిక్యూట్ అవ్వడం వల్ల, ప్రతి పేజీ వ్యూ ఒక కొత్త ఎక్స్పోజర్గా పరిగణించబడింది. హోమ్పేజీలోని రెండు వేరియంట్లు స్వల్పంగా భిన్నమైన లేఅవుట్ ట్రీలను (layout trees) ఉపయోగించాయి, కాబట్టి వాటి పేజీ-వ్యూ రేట్లు వేరుగా వచ్చాయి, దీనివల్ల రాండమైజర్ పాడైపోయిందనే భ్రమ కలిగింది.
ఈ తప్పుడు గణన ఎందుకు ముఖ్యం
కన్వర్షన్ నంబర్లు—క్లిక్-త్రూలు, సైన్-అప్లు, కొనుగోళ్లు—సరైనవేగా నమోదయ్యాయి. కానీ డెనోమినేటర్ (denominator - ఎక్స్పోజర్ల సంఖ్య) తప్పుగా ఉంది. లెక్కించిన కన్వర్షన్ రేట్లు వాస్తవం కంటే చాలా తక్కువగా కనిపించాయి, మరియు ఆ రేట్ల ఆధారంగా తీసుకునే ఏ నిర్ణయమైనా నమ్మదగినవి కావు.
ఈ వ్యత్యాసం బయటపడకముందు టెస్ట్ రెండు వారాల పాటు నడిచింది, దీనివల్ల టీమ్ మొత్తం డేటా సెట్ను పక్కన పెట్టాల్సి వచ్చింది.
పరిష్కారం
పరిష్కారం చాలా సరళమైనది: బాధ్యతలను వేర్వేరు ఫంక్షన్లుగా విభజించడం. ఎక్స్పోజర్-రికార్డింగ్ కోడ్ ఇప్పుడు సందర్శకుడు ఇప్పటికే లెక్కించబడ్డారా లేదా అని తనిఖీ చేస్తుంది, తద్వారా ప్రతి యూజర్కు ఒకే ఒక్కసారి మాత్రమే రన్ అవుతుంది. వేరియంట్-సెట్టింగ్ కోడ్ ఉన్న చోటే ఉంటుంది, ప్రతి నావిగేషన్ సమయంలో రన్ అవుతూనే ఉంటుంది.
ప్రయోగాలు చేసే ఎవరికైనా మూడు ముఖ్యమైన విషయాలు
- స్టేట్-సెట్టింగ్ను (state-setting) వన్-ఆఫ్ ఈవెంట్స్ (one-off events) నుండి వేరు చేయండి. ఒకే ఫంక్షన్ వేరియంట్ను కేటాయించడమే కాకుండా ఎక్స్పోజర్ను కూడా లాగ్ చేస్తే, అవి ఒకదానికొకటి విరుద్ధంగా పనిచేస్తాయి; ఎందుకంటే మొదటిది పదేపదే జరుగుతుంది, కానీ రెండోది జరగకూడదు.
- రూట్ లేఅవుట్లో వన్-షాట్ లాజిక్ను (one-shot logic) నివారించండి. ప్రతి పేజీ లోడ్ అయినప్పుడు రెండర్ అయ్యే కాంపోనెంట్లో ఉంచిన ఏ అంశమైనా పదేపదే ఎగ్జిక్యూట్ అవుతుంది, దీనివల్ల "ప్రతి సందర్శకుడికి ఒకసారి" అనేది "ప్రతి పేజీ వ్యూకి ఒకసారి"గా మారిపోతుంది.
- పరిశీలించిన స్ప్లిట్ రాండమైజర్కు విరుద్ధంగా ఉన్నప్పుడు, మొదట కౌంటర్ను ఆడిట్ చేయండి. డెవలపర్లు తరచుగా రాండమైజర్ యొక్క నిష్పాక్షికతను పరీక్షిస్తారు కానీ కౌంటింగ్ మెకానిజం ఖచ్చితంగా ఉందో లేదో తనిఖీ చేయడం అరుదుగా చేస్తారు.
తదుపరి ఏమి గమనించాలి
ఎక్స్పోజర్ కోసం ఒకే కౌంటర్ మీద ఆధారపడే ఏ ప్రయోగమైనా, ఆ కౌంటర్ కాంపోనెంట్ ట్రీలో ఎక్కడ ఉందో ఆడిట్ చేయాలి. ఒకవేళ కౌంటర్ గ్లోబల్ లేఅవుట్లో ఉంటే, ఆ ఈవెంట్ను కుక్కీ లేదా లోకల్-స్టోరేజ్ ఫ్లాగ్ వంటి పర్సిస్టెంట్ ఐడెంటిఫైయర్తో (persistent identifier) అనుసంధానించేలా ఒక చెక్ జోడించండి. టీమ్లు తమ డ్యాష్బోర్డ్లలో కూడా ఒక శానిటీ చెక్ (sanity check) ఏర్పాటు చేసుకోవాలి: పరిశీలించిన వేరియంట్ డిస్ట్రిబ్యూషన్ చిన్న గణాంక మార్జిన్ కంటే ఎక్కువగా విచలనం చెందితే, రాండమైజర్ పాడైపోయిందని అనుకునే ముందు కౌంటర్ ఆడిట్ కోసం ఆ టెస్ట్ను ఫ్లాగ్ చేయండి.
క్లుప్తంగా చెప్పాలంటే, నమ్మదగిన ఎక్స్పోజర్ కౌంట్ లేనిదే సరిగ్గా పనిచేసే రాండమైజర్ కూడా నిరుపయోగం. బాధ్యతలను విభజించడం మరియు వన్-ఆఫ్ ఈవెంట్లను ఎప్పుడూ రెండర్ అయ్యే కాంపోనెంట్ల వెలుపల ఉంచడం వల్ల A/B టెస్ట్లు ఖచ్చితంగా ఉంటాయి మరియు వారాల కొద్దీ వృథా అయ్యే విశ్లేషణను నివారిస్తుంది.
