Imposter

การทำ A/B Testing ด้วย Firebase Remote Config (Flutter)

Amornthep C
Tri Petch Digital
Published in
8 min readAug 30, 2024

--

  1. A/B Testing คืออะไร?

2. ส่วนประกอบหลักของ A/B Testing

3. จุดเด่นของ A/B Testing

4. ข้อควรระวัง

5. การวางแผน

6. ตัวอย่างการทำ A/B Testing ด้วย Firebase

7. การ Implement ด้วย Flutter

8. สรุป

9. Q &A

1. A/B Testing คืออะไร?

A/B Testing หรือที่รู้จักกันในชื่อ Split Testing เป็นวิธีการทดสอบแบบสุ่มที่ใช้เปรียบเทียบเวอร์ชันที่แตกต่างกันของเว็บไซต์หรือแอปพลิเคชัน ตั้งแต่ 2 เวอร์ชันขึ้นไป โดยมีวัตถุประสงค์เพื่อต้องการข้อมูลเชิงสถิติเพื่อช่วยในการตัดสินใจ และต้องการแน่ใจว่าการเปลี่ยนแปลงที่ทำมีผลกระทบที่ชัดเจนและวัดได้

ตัวอย่าง: สมมติว่าคุณต้องการเพิ่มจำนวนผู้ใช้งานที่ลงทะเบียนบนเว็บไซต์ของคุณ คุณสามารถใช้ A/B Testing เพื่อทดสอบปุ่มลงทะเบียนสองแบบ: สีแดงและสีน้ำเงิน

  • เวอร์ชัน A: เว็บไซต์เวอร์ชันดั้งเดิมที่มีปุ่มลงทะเบียนสีแดง
  • เวอร์ชัน B: เว็บไซต์เวอร์ชันที่ปรับปรุงใหม่ที่มีปุ่มลงทะเบียนสีน้ำเงิน

คุณจะแสดงเวอร์ชัน A และ B ของเว็บไซต์ให้กับผู้ใช้แบบสุ่ม และวิเคราะห์ข้อมูลเพื่อดูว่าเวอร์ชันใดมีจำนวนผู้ใช้ลงทะเบียนมากกว่า

2. ส่วนประกอบหลักของ A/B Testing

  • เป้าหมาย (Goal) เลือกเมตริกที่ต้องการปรับปรุงและตั้งเป้าหมายที่ชัดเจน ตัวอย่างเช่น ในหน้าแรก คุณต้องการให้ผู้ใช้ทั่วไปกดปุ่ม “สร้างโพสต์” มากขึ้น 20–30%
  • สมมติฐาน (Hypothesis) ตั้งสมมติฐานที่จะช่วยให้คุณบรรลุเป้าหมายมากขึ้น ตัวอย่างเช่น การปรับ UI ของปุ่ม “สร้างโพสต์” ให้โดดเด่นยิ่งขึ้น หรือการย้ายตำแหน่งปุ่มให้เห็นได้ชัดเจน จะช่วยเพิ่มจำนวนผู้ใช้ที่กดปุ่มได้
  • ตัวแปร (Variables) เลือกสิ่งที่คุณต้องการทดสอบ ตัวอย่างเช่น ปุ่มหรือข้อความที่ใช้
  • ระยะเวลา (Duration) เลือกระยะเวลาที่จะใช้ในการทดสอบ ต้องมั่นใจว่าระยะเวลาที่ใช้เพียงพอที่จะหาข้อสรุป
  • เมตริก (Metrics) เลือกเมตริกที่เหมาะสมกับการทดสอบ A/B ซึ่งควรเกี่ยวข้องกับเป้าหมายที่ตั้งไว้ ตัวอย่างเช่น ต้องการให้ผู้ใช้ใช้งานไทม์ไลน์มากขึ้น ให้วัดจากระยะเวลาที่ผู้ใช้ใช้งานฟีเจอร์ที่เกี่ยวข้องกับไทม์ไลน์ หรือจำนวนครั้งการกด Reaction ต่างๆ
  • กลุ่มทดสอบ (Test group) กลุ่มผู้ใช้งานที่ถูกเลือกให้ทดสอบ ควรมีลักษณะเป็นกลุ่มคล้ายๆ กัน เช่น กลุ่มช่วงอายุเดียวกัน เพศ หรือ ยังไม่เคยใช้งานฟีเจอร์บางอย่างมาก่อน โดยสุ่มเฉลี่ยให้กลุ่มทดสอบมีขนาดพอๆ กัน

3. จุดเด่นของ A/B Testing

  • ข้อมูลเชิงสถิติที่เชื่อถือได้: ใช้วิธีทำการทดสอบหลาย Varaint ไปพร้อมกัน ทำให้ตัดปัจจัยที่มีผลกับช่วงเวลา หรือปัจจัยภายนอกที่ส่งผลกับการใช้งาน อย่างเช่นการทำแคมเปญกิจกรรม, การ Promote ทางช่องทางต่างๆ ทำให้มั่นใจได้ว่า ข้อมูลที่ได้มานั้นอยู่บนสภาพแวดล้อมเดียวกัน
  • ลดความเสี่ยงจากการเปลี่ยนแปลง: ทำการทดสอบการเปลี่ยนแปลงกับกลุ่มผู้ใช้บางส่วนก่อนที่จะนำไปใช้จริง ทำให้ลดความเสี่ยงที่จะเกิดผลกระทบเชิงลบต่อผู้ใช้ทั้งหมด หากผลการทดสอบไม่เป็นไปตามที่คาดหวัง ยังสามารถหยุดการทดสอบและกลับไปใช้ Varaint เดิมได้
  • ลดเวลาที่ใช้ทดสอบ: สามารถทำการทดสอบพร้อมกันได้หลาย Varaint จึงไม่ต้องเสียเวลาทำการทดสอบทีละ Varaint แล้วค่อยเปรียบเทียบผลลัพธ์เพื่อหาข้อสรุป

4. ข้อควรระวัง

4.1 Running Complex Tests (การทดสอบที่ซับซ้อน)

ควรทำการทดสอบทีละ Varaint ในการทดสอบแต่ละครั้ง เพื่อให้สามารถระบุได้อย่างชัดเจนว่าการเปลี่ยนแปลงใดส่งผลต่อผลลัพธ์ที่เกิดขึ้น หากทำการทดสอบที่มีหลาย Varaint หรือหลายองค์ประกอบที่เปลี่ยนแปลงพร้อมกันในการทดสอบเดียว จะทำให้เกิดปัญหาในการวิเคราะห์ผลลัพธ์และไม่สามารถระบุสาเหตุที่แท้จริงของการเปลี่ยนแปลงได้ เช่น ต้องการเพิ่มยอดขายสินค้าบนเว็บไซต์ โดยทำการเปลี่ยนแปลง 3 อย่างพร้อมกัน:

  • เปลี่ยนสีปุ่ม “ซื้อเลย” จากสีแดงเป็นสีเขียว
  • เพิ่มขนาดรูปภาพสินค้าให้ใหญ่ขึ้น
  • เปลี่ยนตำแหน่งของปุ่ม “ซื้อเลย” ให้อยู่ด้านบนของหน้าแทนที่จะอยู่ด้านล่าง

หลังจากทำการทดสอบ พบว่ายอดขายเพิ่มขึ้น แต่ปัญหาคือไม่สามารถระบุได้ว่าการเปลี่ยนแปลงใดเป็นสาเหตุสำคัญที่ทำให้ยอดขายเพิ่มขึ้น

4.2 Not Testing with a Hypothesis (การทดสอบโดยไม่มีสมมติฐาน)

การตั้งสมมติฐานจะช่วยให้สามารถกำหนดเป้าหมายและทิศทางของการทดสอบโฟกัสไปที่การเปลี่ยนแปลงที่คาดว่าจะส่งผลต่อเมตริกที่ต้องการปรับปรุง

วิธีการตั้งสมมติฐาน:

  1. วิเคราะห์ข้อมูลที่มีอยู่: ศึกษาข้อมูลการใช้งาน, ข้อมูลลูกค้า, หรือผลการทดสอบก่อนหน้า เพื่อระบุปัญหาหรือแนวทางในการปรับปรุง
  2. สังเกตพฤติกรรมผู้ใช้: ลองใช้งานผลิตภัณฑ์ในมุมมองของผู้ใช้ เพื่อทำความเข้าใจประสบการณ์การใช้งาน และระบุจุดที่อาจทำให้เกิดปัญหา
  3. ระบุตัวแปรและการเปลี่ยนแปลง: เลือกตัวแปรที่คุณต้องการทดสอบ และกำหนดการเปลี่ยนแปลงที่คุณคิดว่าจะส่งผลดีต่อเมตริกที่ต้องการปรับปรุง

ตัวอย่างสมมติฐาน:

  • ลองใช้งานในมุมมองของผู้ใช้ ดูว่าอะไรเป็นปัญหาในการใช้งาน เช่น มีผู้ใช้งานเข้ามาดู Timeline detail เยอะ แต่มี reaction น้อย พอเราลองเล่นหน้า detail พบว่า ปุ่ม reaction มีขนาดเล็กและไม่เด่นพอที่จะเป็นจุดสนใจ เมื่อพอรู้ปัญหาแล้วก็ลองหาวิธีแก้ต่อ
  • ตัดสินใจเลือกวิธีการแก้ปัญหาที่เกิดขึ้น เช่น เพิ่มขนาดปุ่ม, เปลี่ยนสี, ย้ายตำแหน่งให้เห็นชัดเจนมากขึ้น, หรือเปลี่ยนคำที่ใช้ หลังจากได้ วิธีแก้ปัญหามาแล้ว ลองเลือกวิธีที่ดูมี impact ชัดเจน เพื่อใช้ในการตั้ง สมมติฐาน
  • สร้างสมมติฐานขึ้นมาโดยอ้างอิงจากปัญหาและแนวทางแก้ไข จากข้างต้นสมมติฐานคือ “การทำให้ปุ่ม reaction เด่นชัดมากขึ้น จะส่งผลให้ ผู้ใช้งาน มีการทำ reaction ที่เยอะขึ้น”

4.3 Stopping Tests Too Early (หยุดการทดสอบเร็วเกินไป)

  • บางครั้งเมื่อเริ่มการทดสอบ ผลลัพธ์อาจออกมาชัดเจนตั้งแต่ช่วงแรก แต่ไม่ควรหยุดการทดสอบเร็วเกินไปเพราะอาจมีปัจจัยอื่นๆ ที่ส่งผลต่อผู้ใช้งาน เช่น ช่วงวันหยุด, เทศกาล หรือการมาโดยผ่าน campagin อื่นๆ อย่าง facebook, line
  • ควรทดสอบจนมั่นใจว่าผลลัพธ์ที่ได้มีนัยยะทางสถิติที่ถูกต้อง
  • สามารถใช้เครื่องมือคำนวณขนาดตัวอย่างเพื่อประกอบการตัดสินใจ Sample size calculator

4.4 Focusing on the Wrong Areas (เน้นการทดสอบผิดจุด)

  • บางอย่างเราสามารถหาคำตอบได้จากแหล่งข้อมูลอื่น ตัวอย่างเช่น ขนาดที่เหมาะสมของวิดีโอ หรือรูปแบบการแสดงสินค้า จากแอปชั้นนำอื่น ๆ
  • นอกจากนี้ยังมีแนวทางการออกแบบ (Design guideline) ที่มีการทำวิจัยมาแล้วเกี่ยวกับการใช้สี font การวางตำแหน่ง หรือรูปแบบของปุ่ม ที่เหมาะสม

5. การวางแผน

การวางแผนที่ดี มีส่วนสำคัญอย่างยิ่งต่อความสำเร็จของ A/B Testing

5.1 กำหนดสิ่งที่ต้องการปรับปรุง (Determine What to Improve)

วิเคราะห์ข้อมูล (Data Analysis) ที่มีอยู่ มองหาจุดที่สามารถปรับปรุงได้ ตัวอย่างเช่น

  • หน้าบางหน้าที่มีการเข้าใช้งานน้อยกว่าที่ตั้งเป้าหมาย
  • เวลาเฉลี่ยของการใช้งานแต่ละหน้าต่ำเกินไป
  • Conversion rate น้อยกว่าที่คาดการณ์ไว้

5.2 ระบุตัวแปรที่จะทดสอบ (Identify a Variable)

  • เลือกปัจจัยที่คิดว่าส่งผลต่อสิ่งที่ต้องการปรับปรุง ตัวอย่างเช่น ปุ่ม, ข้อความที่ใช้แสดง หรือ ตำแหน่งของ Element ต่างๆ

5.3 ตั้งสมมติฐานการทดสอบ (Settle on a Test Hypothesis)

  • กำหนดทิศทางการเปลี่ยนแปลงที่คาดว่าจะส่งผลดีขึ้น ตัวอย่าง การทำให้ปุ่ม Call-to-Action เด่นชัดมากขึ้น จะส่งผลให้ User มีการคลิกปุ่มมากขึ้น

5.4 กำหนดเป้าหมาย ระยะเวลา และกลุ่มทดสอบ (Set Your Goals, Test Period, and Sample Size)

5.4.1 เป้าหมาย (Goals): ระบุผลลัพธ์ที่ต้องการวัดหลังการทดสอบ ตัวอย่างเช่น

  • Conversion rate
  • Average time on page
  • Bounce rate

5.4.2 ระยะเวลาการทดสอบ (Test Period):

  • กำหนดช่วงเวลาที่เหมาะสมในการเก็บข้อมูล ขึ้นอยู่กับปริมาณ Traffic ของเว็บไซต์หรือแอปพลิเคชัน

5.4.3 กลุ่มทดสอบ (Sample Size):

  • กลุ่มผู้ใช้งานที่ถูกสุ่มเลือกเข้าร่วมทดสอบ ควรมีขนาดที่เพียงพอที่จะได้ผลลัพธ์ที่มีนัยยะทางสถิติ
  • เครื่องมือคำนวณขนาดตัวอย่าง Sample size calculator

ตัวอย่าง: ต้องการเพิ่ม Conversion rate 20% ใช้เวลาดำเนินการทดสอบ 30 วัน กลุ่มทดสอบคิดเป็น 30% ของผู้ใช้งานทั้งหมด

5.5 สร้างรูปแบบการทดสอบ (Create Variations Based on Your Hypothesis)

กำหนดรูปแบบที่แตกต่างกันไปตามสมมติฐาน ตัวอย่างเช่น

  • เปลี่ยนปุ่ม Call-to-Action จากขนาดเล็กเป็นขนาดใหญ่ขึ้น และมีข้อความประกอบชัดเจน
  • เปลี่ยนสีปุ่ม Call-to-Action ให้เด่นขึ้น

5.6 เริ่มการทดสอบ (Run Your Test)

  • เริ่มทดสอบเวอร์ชันต่างๆ ของเว็บไซต์หรือแอปพลิเคชันตามที่กำหนด
  • ใช้เครื่องมือ A/B Testing ในการจัดการและติดตามผลการทดสอบ

5.7 วิเคราะห์ผลลัพธ์และวางแผนการดำเนินการต่อไป (Analyze the Results and Plot Your Next Steps)

หลังจากครบกำหนดระยะเวลาการทดสอบ วิเคราะห์ข้อมูลที่ได้จากทั้งเวอร์ชันดั้งเดิม (Base version) และเวอร์ชันทดสอบ (Variation) เปรียบเทียบผลลัพธ์ตามเป้าหมายที่ตั้งไว้

5.7.1 กรณีผลทดสอบเป็นไปตามสมมติฐาน

  • นำเวอร์ชันทดสอบที่ได้ผลลัพธ์ดีกว่าไปปรับใช้จริงบนเว็บไซต์หรือแอปพลิเคชัน

5.7.2 กรณีผลทดสอบไม่ได้เป็นไปตามสมมติฐาน

  • วิเคราะห์หาสาเหตุที่ทำให้ผลลัพธ์ไม่เป็นไปตามที่คาดการณ์ไว้
  • ปรับปรุงการออกแบบหรือตั้งสมมติฐานในมุมมองใหม่ บนข้อมูลที่ได้มา และทำการทดสอบเพิ่มเติม

5.8 บันทึกผลการทดสอบ (Document Your Findings)

บันทึกสิ่งที่ค้นพบระหว่างการทดสอบ รวมถึงผลลัพธ์ที่ได้ บันทึกข้อมูลเหล่านี้เพื่อนำไปใช้ประโยชน์ในการทดสอบครั้งต่อไป

6. ตัวอย่างการทำ A/B Testing ด้วย Firebase

Timeline & Profile

สถานการณ์: ต้องการเพิ่มจำนวนผู้ใช้งานที่กดดูโปรไฟล์บนหน้า Timeline ของแอปพลิเคชัน เพื่อเพิ่มโอกาสในการกดติดตาม

สมมติฐาน: การขยายรูปโปรไฟล์ให้ใหญ่ขึ้นบนหน้า Timeline จะช่วยเพิ่มจำนวนผู้ใช้งานที่กดดูโปรไฟล์

การทดสอบ:

Create Firebase Remote Config Experiments with A/B Testing

6.1 สร้างการทดสอบ: ไปที่ Firebase console เลือก A/B Testing ถ้าหาไม่เจอ ให้หาใน Product Category => Run => A/B Testing จากนั้นตรวจสอบ Project ที่ต้องการใช้งาน ถ้าทุกอย่างเรียบร้อยแล้วกด Create experiment ได้เลย

สร้างการทดสอบ

6.2 ตั้งชื่อการทดสอบ: ตั้งชื่อการทดสอบ สามารถใส่คำอธิบายเพิ่มเติมได้

ตั้งชื่อการทดสอบ

6.3 ตั้งค่า Targeting: เลือก App ที่ต้องการใช้งาน ถ้ามีมากกว่าหนึ่ง App ต้องทำการแยก Test สามารถทำ Duplicate ในภายหลังได้ และสามารถเลือก specific เพิ่มเติมได้แก่

  • Version
  • Build number
  • First open เป็น User ใหม่ หรือ เลือกเป็นช่วงเวลาก็ได้
  • Languages ของ Device
  • Country/Region
  • User audiesnce มีให้เลือกทำ operation ได้ 3 อย่างคือ All users, Purchasers หรือ User property
  • User property

โดยเราต้องการกลุ่มเป้าหมายที่ไม่ใช่ User Demo ให้เลือกเป็น User property และเลือก is_demo เป็น false

ต่อมาเลือก % ของผู้เข้าร่วมในการทดสอบของกลุ่มนี้

เราสามารถ ระบุ Activation event ที่อยากให้ User มีการ Trigger ก่อนถึงจะนำมาคำนวณผลลัพธ์ก็ได้

Targeting

6.4 เลือก Goals: สามารถเป็น Revenue, Retention หรือ Analytic event ก็ได้

  • Primary Goal: เราเลือกเป็น Event = “timeline_profile_click” เป็น Goal หลัก เพื่อวัดจำนวนผู้ใช้งานที่กดดูโปรไฟล์
  • Additional Metrics: เราเลือกเป็น Event = “follow_click” เป็น Additional Metrics เพื่อดูจำนวนผู้ใช้งานที่กดติดตามเพิ่มเติม แต่ไม่มีผลต่อการคำนวณ Goal หลัก
Goal

6.5 สร้าง Variants: สามารถมีได้มากกว่า 2 ในที่นี้เราต้องการแค่ 2 variants คือที่เป็นขนาดเท่าเดิมกับที่มีขนาดใหญ่ขึ้น เราสามารถกำหนด weights ของ variants เองได้ ส่วน parameter เราจะสร้างขึ้นใหม่ หรือเอาจาก Remote Config มาใช้ก้ได้

  • Baseline: รูปโปรไฟล์ขนาดปกติ ให้มีค่า “timeline_profile_image_size” = “default”
  • Variant A: รูปโปรไฟล์ขนาดใหญ่ ให้มีค่า “timeline_profile_image_size” = “large”
Variants & Weights

6.6 เมื่อสร้างเสร็จแล้วเราจะได้ status เป็น Draft ถ้าเรามีมากกว่า 1 App ให้ทำการ Duplicate แล้วเปลี่ยน Target app เอา

Duplicate

6.7 เริ่มการทดสอบ: เมื่อพร้อมแล้วกดปุ่ม “Start experiment” ได้เลย

Let start!!

ผลลัพธ์:

หลังจากสิ้นสุดระยะเวลาการทดสอบ เราสามารถวิเคราะห์ผลลัพธ์เพื่อดูว่า Variant ใดมีประสิทธิภาพดีกว่า

กรณี Variant A มีประสิทธิภาพดีกว่า:

  • แสดงว่าการขยายรูปโปรไฟล์ให้ใหญ่ขึ้นช่วยเพิ่มจำนวนผู้ใช้งานที่กดดูโปรไฟล์ได้จริง
  • ควรใช้ขนาด “large” สำหรับผู้ใช้งานทั้งหมด หรือ ปรับค่า Remote Config “timeline_profile_image_size” ให้เป็น “large”

กรณี Baseline มีประสิทธิภาพดีกว่าหรือไม่ต่างจาก Variant A:

  • แสดงว่าการขยายรูปโปรไฟล์ให้ใหญ่ขึ้นไม่มีผลต่อจำนวนผู้ใช้งานที่กดดูโปรไฟล์
  • ควรเก็บข้อมูลเพิ่มเติม หรือตั้งสมมติฐานใหม่ ในการทดสอบใหม่ครั้งต่อไป
ตัวอย่างผลลัพธ์

7. การ Implement ด้วย Flutter

7.1 เตรียม Remote Config

ก่อนอื่น เราต้องเตรียม Remote Config ตัวอย่างนี้ใช้ Firebase Remote Config ร่วมกับ Riverpod ในการจัดการ State แบบ Realtime

  1. เพิ่ม dependencies ใน pubspec.yaml:
dependencies:   
firebase_core: ^1.12.0
firebase_remote_config: ^2.1.0
flutter_riverpod: ^1.0.0

2. สร้าง Service และ Entity ของ Remote Config

my_remote_config/entities/remote_config.dart

enum ProfileImageSize{ normal, large }
class RemoteConfig {
const RemoteConfig({ required this.timelineProfileImageSize });
factory RemoteConfig.defaultValue() => const RemoteConfig(
timelineProfileImageSize: ProfileImageSize.normal,
);
final ProfileImageSize timelineProfileImageSize;
}

my_remote_config/services/remote_config_service_interface.dart

abstract class RemoteConfigServiceInterface {
Future<RemoteConfig> getRemoteConfig();
void onUpdateRemoteConfig(Function(RemoteConfig remoteConfig) onUpdated);
}

my_remote_config/services/firbase_remote_config_service.dart

class FirebaseRemoteConfigService implements RemoteConfigServiceInterface {
StreamSubscription? subscription;

@override
Future<RemoteConfig> getRemoteConfig() async {
//check Firebase initialized
if (Firebase.apps.isEmpty) {
await Firebase.initializeApp();
}
final remoteConfig = FirebaseRemoteConfig.instance;
//setting Firebase Remote Config
await remoteConfig.setConfigSettings(RemoteConfigSettings(
fetchTimeout: const Duration(minutes: 1),
minimumFetchInterval: const Duration(hours: 1),
));

try {
await remoteConfig.fetchAndActivate(); // fetch and activate value to local
} catch (e) {
return RemoteConfig.defaultValue();
}

return _convertToRemoteConfigEntity(remoteConfig);
}

RemoteConfig _convertToRemoteConfigEntity(FirebaseRemoteConfig remoteConfig) {
final profileImageSize =
remoteConfig.getString('timeline_profile_image_size') == 'large' ? ProfileImageSize.large : ProfileImageSize.normal;

final config = RemoteConfig(
timelineProfileImageSize: profileImageSize,
);
return config;
}

@override
Future<void> onUpdateRemoteConfig(Function(RemoteConfig remoteConfig) onUpdated) async {
final remoteConfig = FirebaseRemoteConfig.instance;
// clear old subscription
if (subscription != null) {
await subscription?.cancel();
subscription = null;
}
//subscribe onConfigUpdated for update real time
subscription = remoteConfig.onConfigUpdated.listen((event) async {
//activate new value
await remoteConfig.activate();
//convert new value and notify callback
onUpdated.call(_convertToRemoteConfigModel(remoteConfig));
}, onError: (e) {
//Handle error 'FirebaseRemoteConfig StreamSubscription'
});
}
}

3. สร้าง Singleton ไว้จัดการ RemoteConfig และใช้งานภายใน Application

my_remote_config/my_remote_config.dart

class MYRemoteConfig {
MYRemoteConfig._privateConstructor();

static final MYRemoteConfig _instance = MYRemoteConfig._privateConstructor();

static MYRemoteConfig get instance => _instance;

RemoteConfig? _remoteConfig;

RemoteConfig get remoteConfig => _remoteConfig ?? RemoteConfig.defaultValue();

//Injection
RemoteConfigServiceInterface _service = FirebaseRemoteConfigService();

Future<void> init() async {
final result = await _service.getRemoteConfig();
_remoteConfig = result;
}

void addListener(WidgetRef ref) {
_service.onUpdateRemoteConfig((value) {
_remoteConfig = value;
ref.read(remoteConfigProvider.notifier).state = value;
});
}
}

4. สร้าง Provider ไว้ใช้ในส่วนของ Widget ที่ต้องการ Update real time

my_remote_config/remote_config_provider.dart

final remoteConfigProvider = StateProvider.autoDispose<RemoteConfig>((ref) => MYRemoteConfig.instance.remoteConfig);

7.2 Integrate MYRemoteConfig

1. init ที่ส่วนของการ Initialize App

void main() {
WidgetsFlutterBinding.ensureInitialized();
MYRemoteConfig.instance.init(); // Init Remote Config
runApp(MyApp());
}

2. add listener ในส่วนที่เป็น Main widget

class MyApp extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
MYRemoteConfig.instance.addListener(ref);

3. สร้าง Testing Widget ที่ทำหน้าที่เลือกใช้ Widget ในการแสดงตาม Remote config ที่ได้เพื่อให้ง่ายต่อการค้นหา และไม่เป็น Dependency กับ Widget หลักที่ใช้งาน

class TimelineProfileImageSizeTestingWidget extends ConsumerWidget {
const TimelineProfileImageSizeTestingWidget({
required this.normal,
required this.large,
super.key,
});

final Widget normal;
final Widget large;
@override
Widget build(BuildContext context, WidgetRef ref) {
// ใช้ watch เพื่อจะได้รองรับการ update แบบ real time และ select เฉพาะค่าที่สนใจ
final size = ref.watch(remoteConfigProvider.select((value) => value.profileImageSize));
switch (size) {
case ProfileImageSize.large:
return large;
case ProfileImageSize.normal:
return normal;
}
}
}

4. เมื่อพร้อมแล้วเราก็นำ Testing Widget ไปใช้งานในส่วนที่ต้องการทำ A/B Test ได้เลย

TimelineProfileImageSizeTestingWidget(
normal: ProfileButton(), // Widget ที่แสดงรูปแบบปกติ
large: ProfileLargeButton(), // Widget ที่แสดงแบบที่ขนาดใหญ่ขึ้น
)

7.3 ตรวจสอบให้แน่ใจว่ามีการ Implement การส่ง Event ถูกต้องตามที่เราตั้งไว้

  • timeline_profile_click
  • follow_click

ผลลัพธ์ที่ได้

Result

7.4 ลบสิ่งที่ไม่ได้ใช้หลังจากการทดสอบเสร็จสิ้น

หลังจากการทดสอบเสร็จสิ้นและได้ผลลัพธ์ที่ชัดเจนแล้ว คุณสามารถลบโดยเริ่มจาก TimelineProfileImageSizeTestingWidget และไล่ลบ Reference ที่เกี่ยวข้องที่ไม่ได้ใช้งานออกไปได้

8. สรุป

A/B Testing เป็นเครื่องมือที่มีประสิทธิภาพในการใช้ตัดสินใจ ได้เห็นภาพจากผลลัพธ์ที่น่าเชื่อถือ โดยใช้ข้อมูลสถิติ วัดผลกระทบได้แม่นยำ และลดความเสี่ยงจากการเปลี่ยนแปลงได้ อย่างไรก็ตาม A/B Testing ไม่ได้เหมาะสมกับทุกสถานการณ์ หากมีข้อจำกัดด้านเวลา ทรัพยากร หรือข้อมูล หรือต้องการทำการเปลี่ยนแปลงครั้งใหญ่ อาจจะต้องพิจารณาวิธีการทดสอบในรูปแบบอื่น ที่เหมาะสมกว่า

9. Q &A

Q: ตรง Not Testing with a Hypothesis นี่แอบไม่ค่อยเคลียร์อ่ะ เราบอกไม่ให้เดา แต่ในตัวอย่างบอกให้ไปลองเล่น แล้วพอเจอว่าคนกด reaction น้อย การที่เราบอกว่าปุ่มมันเล็ก ต้องเปลี่ยนสี มันก็ยังนับว่าเป็นการเดาอยู่หรือเปล่านะ แอบอยากรู้ว่าในมุมของ designer เขามีวิธีมอง หรือมีคำอธิบายชัดๆ มั้ยว่า UI/UX แบบไหนที่มีปัญหาแล้วควรเปลี่ยน เสร็จแล้วเราอาจจะมอง A/B testing ว่าเป็นหนทางแห่งการพิสูจน์แนวคิดนั้นๆ ว่าจริงหรือไม่จริง

A: ใช่ก็คือการเดาแบบมีข้อมูล จากตัวอย่าง เราใช้ข้อมูลจากการ Role Play เป็น User หรือถ้าจะเอาชัดกว่านั้นก็ อาจจะอิงจากหน้า Timeline detail ที่มีมีการกดที่ Profile สูงกว่าสองหน้านี้ต่างกันที่ขนาดที่แสดง จึงคิดว่าถ้าเพิ่มขนาดจะมีผลต่อการกดด้วย หรือจะเป็น เมื่อลองเปรียบเทียบกับ App Social หลักๆ ที่มีลักษณะคล้ายกัน มีการใช้ Profile ที่มีขนาดพอๆ กันหมด น่าจะเป็นขนาดมาตราฐานที่คิดกันมาแล้วว่าเหมาะสม ซึ่งของเรามีความเล็กกว่า การเพิ่มขนาดจะทำให้ UX ดีขึ้น ส่วนมุมมอง ของ Designer จะมีหลัก Heuristics ช่วยในการตรวจสอบเบื้องต้น เมื่อพบว่ามีปัญหาอาจจะใช้เป็น User Testing ช่วยหาคำตอบ หรือ จะใช้ A/B Test เมื่อมีคำตอบที่คิดไว้มากกว่าหนึ่งและไม่มั่นใจว่าควรเลือกใช้คำตอบไหน

Q: เมื่อไหร่ควรใช้ A/B Testing และเมื่อไหร่ไม่ควรใช้

A: เมื่อไหร่ควรใช้

  • ต้องการวัดผลลัพธ์ที่ชัดเจน: สามารถเปรียบเทียบการเปลี่ยนแปลงได้โดยหลีกเลี่ยงความแตกต่างของสภาพแวดล้อม ที่จะทำให้ข้อมูลมีความเอนเอียง เช่น ทำการเปลี่ยนแปลงในระหว่างที่มีการทำ campagin ซึ่งให้ให้ข้อมูลที่ได้มีทิศทางไปในทางที่ดีขึ้น
  • มีหลายตัวเลือกให้ตัดสินใจ: บางครั้งวิธีการแก้ปัญหามีได้หลายทางเลือกแต่ไม่สามารถหาข้อสรุปชี้ชัดได้ว่าควรเลือกใช้วิธีการไหน เช่น หน้า login มีการ login ผิดพลาดจากการใส่ username ที่ไม่ถูกต้องเป็นจำนวนมากโดยใช้คำว่า ‘ชื่อผู้ใช้งาน’ เป็น hint ซึ่งต้องเป็นชื่อบัญชีที่ผู้ใช้ได้สร้างเอาไว้ตอนสมัครสมาชิก แต่มีการใส่เป็นชื่อจริงของผู้ใช้งานมาเป็นจำนวนมาก เลยต้องการลดข้อผิดพลาดนี้ แต่ตัดสินใจไม่ได้ว่าควรใช้วิธีไหนดี โดยมีตัวเลือกคือ
    1.เปลี่ยน hint ของ username พร้อมยกตัวอย่างเป็น ‘ชื่อบัญชีผู้ใช้ ตัวอย่าง username_a’
    2.เปลี่ยน hint ของ username เป็น ‘ชื่อบัญชีผู้ใช้’ พร้อมเพิ่ม remark ใต้ Field username ‘บัญชีผู้ใช้ คือ ชื่อบัญชีที่ได้จากขั้นตอนการสมัครสมาชิก’
    3.ใช้ hint เหมือนข้อ 1 และเพิ่ม remark เหมือนข้อ 2
  • ไม่มั่นใจในการเปลี่ยนแปลง: บางครั้งเป็น Feature หลักที่ส่งผลกับการใช้งาน หากผลลัพธ์ของการเปลี่ยนแปลงไม่เป็นไปตามที่ตั้งเป้าไว้ จะได้ไม่ส่งผลกระทบต่อผู้ใช้ทั้งหมด เช่นเป็นผู้ให้บริการ Ecommerce ได้มีการ redesign หน้ารายละเอียดสินค้า ซึ่งจะกระทบต่อยอดขายสินค้า จึงควรทำการทดสอบกับผู้ใช้งานบางส่วนก่อนเพื่อลดความเสียหายที่อาจจะเกิดขึ้น

เมื่อไหร่ควรเลี่ยง

  • การเปลี่ยนแปลงที่ซับซ้อน: ยิ่งทำการทดสอบกับการเปลี่ยนแปลงที่มีความซับซ้อนมาก ยิ่งต้องใช้ resource เพิ่มขึ้นเช่น การปรับปรุงขั้นตอนการสมัครสมาชิก ซึ่งมีการปรับทั้งขั้นตอนและ design ไปพร้อมกัน ทำให้มีจุดที่ต้อง Implement A/B Test หลายจุด ใช้เวลาเพิ่มขึ้นในการ Implement และการ Clean code หลังจากทำการทดสอบ ดังนั้น หากมี resource จำกัด อาจใช้วิธีการอื่นเพื่อตรวจสอบผลลัพธ์แทน
  • มีกลุ่มทดสอบไม่เพียงพอ: บางหน้าหรือบาง Feature มีผู้ใช้งานน้อยเกินไป ทำให้ผลลัพธ์ของการทดสอบ ไม่ค่อยมีความน่าเชื่อถือทางสถิติ เช่น ในหน้า Policy มีผู้ใช้งาน 100 คน มี conversion rate ของการเลื่อน อ่านอยู่ที่ 10% ต้องการเพิ่มเป็น 15 % จึงทำการ Redesign แล้วทำการทดสอบ แต่ตามหลักการแล้วต้องใช้ผู้ทดสอบอย่างน้อย 390 คนถึงจะทำให้ผลลัพธ์ที่ได้มีความน่าเชื่อถือทางสถิติ

Q: เวลาทดสอบแล้วไม่เป็นไปตามสมมติฐาน เราต้อง revert กลับเป็น base variant มั้ย แล้วถ้าจะทดสอบ variant อื่นๆ เราควรลองไปจนถึงจุดๆ ไหนถึงจะบอกได้ว่าควรเลิกพยายาม

A: A/B Test ทำมาเพื่อการทดสอบอยู่แล้วเมื่อถึงจุดหนึ่งเราต้องเลือกสิ่งเดียวที่เหลือรอด ซึ่งจะเลือก A หรือ B ก็แทบไม่มีผลเพราะ conversion ไม่ต่างกัน แล้วควรพยายามถึงไหน ขึ้นอยู่กับหลายปัจจัย เช่น

  • Resource ที่มี ทั้งเรื่อง คน, เวลา และ งบประมาณ
  • ความคุ้มค่ากับการที่ต้องหาคำตอบนี้ต่อ
  • ยังมั่นใจว่าจะสามารถหาคำตอบนี้ได้ ด้วยการทำ AB Testing
  • ข้อมูลที่ได้มาจากการทำ A/B Tesing ยังมีค่าในการใช้หาคำตอบ ในการทำการทดสอบใหม่

Q: Variants ควรมีไม่เกินกี่อัน

A: มีได้ตามสมมุติฐานที่เราสร้างขึ้นนะ แต่มันจะถูกควบคุมด้วย การที่ต้องใช้กลุ่มตัวอย่างที่เยอะขึ้น สามารถคำนวนได้จาก Calculate ตัวอย่าง ใน version baseline มี conversion rate อยู่ที่ 20% เราตั้งสมมุติฐานที่ต้องการให้มี conversion rate เพิ่มขึ้น 10% หมายความว่าเราต้องใช้กลุ่มตัวอย่าง 5,300 ต่อ 1 Varaint ถ้ามี 4 varaints ต้องใช้ 5,300 * 4 = 21,200 user เพื่อที่จะหาคำตอบ ซึ่งจะมีเรื่อง Group Target ที่เราอยากทดสอบแค่กับคนบางกลุ่ม ทำให้ ตัวอย่างทดสอบของเราจะไม่เพียงพอสำหรับการหาคำตอบที่เหมาะสมในการทดสอบนี้

Q: เมื่อเกิด A/B ขึ้น จะต้องมีการสร้าง backlog เพื่อกลับมา clean code หรือไม่ โดยใคร อย่างไร ต้องมีกำหนดระยะเวลาเสมอรึเปล่า

A: ควรมี Backlog คู่กันไป แยกเป็นการสร้าง กับการจัดการเมื่อได้ผลลัพธ์ หรือได้ทดสอบตามระยะเวลาที่ครบกำหนดแล้ว โดยกรณีที่ A/B Test Failed และไม่มี Plan จะ Test ต่อก็สามารถ Clean code กับ Config ทิ้งใน Version ถัดไปได้เลย ส่วนกรณีที่ได้ผลลัพธ์ ตามข้อสมมติฐานที่เราสร้างขึ้น ก็สามารถ Clean code ใน Version ถัดไปได้เลย ส่วนในตัว Config ต้องใส่ Note version ที่ทำการ Clean Code แล้วไว้ก่อน หรือทำ Condition Version ทิ้งไว้ พอมีการ Froce upgrade ก็สามารถ Clear Config ที่มี Note version ที่ต่ำกว่า Version ที่ Force Upgrade ได้

--

--