จาก 250 คำสั่งเหลือ 7 — กฎข้อเดียวที่ทำให้หน้าเว็บเร็วขึ้น
หน้ารายการออเดอร์ออนไลน์ของเราเคยโหลดช้าจนพนักงานหลีกเลี่ยงที่จะเปิด
สาเหตุไม่ใช่ข้อมูลเยอะ และไม่ใช่เซิร์ฟเวอร์ไม่แรง แต่เป็นรูปแบบการเขียนโค้ดที่อ่านแล้วดูสะอาดที่สุด
ปัญหา
การ์ดแสดงออเดอร์หนึ่งใบต้องแสดงข้อมูลหลายส่วน — ข้อมูลผู้ซื้อ เอกสารที่เกี่ยวข้อง ข้อมูลใบกำกับภาษี รายการสินค้าพร้อมรูป ยอดรวม
วิธีเขียนที่เป็นธรรมชาติที่สุดคือ ให้ชิ้นส่วนการ์ดไปดึงข้อมูลที่ตัวเองต้องการมาเอง เพราะทำให้ชิ้นส่วนนั้นสมบูรณ์ในตัว เอาไปวางตรงไหนก็ใช้ได้ทันที ไม่ต้องให้ผู้เรียกเตรียมอะไรให้
ปัญหาคือหน้ารายการแสดงการ์ดครั้งละหลายสิบใบ
เมื่อการ์ดหนึ่งใบดึงข้อมูล 5 ครั้ง การแสดง 50 ใบจึงกลายเป็น 250 คำสั่งไปยังฐานข้อมูลต่อการเปิดหน้าหนึ่งครั้ง
แต่ละคำสั่งเร็วมาก อาจใช้เวลาแค่ไม่กี่มิลลิวินาที ซึ่งเป็นเหตุผลที่ปัญหานี้รอดมาได้นาน — ไม่มีคำสั่งไหนช้าพอจะปรากฏในรายงานว่าเป็นตัวปัญหา มีแต่จำนวนที่มากเกินไป
ทำไมแก้ทีละจุดถึงไม่ได้ผล
ทางแก้ที่คนมักทำคือไล่หาจุดที่ช้าแล้วแก้ทีละที่ วิธีนี้ได้ผลชั่วคราวแต่กลับมาใหม่เสมอ
เพราะรากของปัญหาไม่ใช่โค้ดจุดใดจุดหนึ่ง แต่เป็นรูปแบบการเขียนที่เชิญชวนให้ทำผิดซ้ำ ตราบใดที่ชิ้นส่วนยังดึงข้อมูลเองได้ คนที่มาเพิ่มข้อมูลลงการ์ดในอนาคตก็จะเพิ่มการดึงข้อมูลเข้าไปอีก โดยไม่รู้เลยว่าตัวเองเพิ่งเพิ่มคำสั่งไปฐานข้อมูล 50 ครั้ง
คนเขียนเห็นแค่โค้ดของการ์ดหนึ่งใบ ไม่เห็นว่ามันถูกเรียกกี่ครั้ง
สิ่งที่เราทำ
เราตั้งกฎเดียวและบังคับมันตั้งแต่ตอนออกแบบ
ห้ามดึงข้อมูลจากภายในชิ้นส่วนที่ใช้แสดงผล — ข้อมูลทั้งหมดต้องถูกเตรียมมาให้ครบก่อน
ตัวประกอบข้อมูลจะรับรายการออเดอร์ทั้งหน้ามาพร้อมกัน แล้วดึงข้อมูลที่ต้องใช้เป็นชุดเดียว — ดึงข้อมูลผู้ซื้อของทุกออเดอร์ในคำสั่งเดียว ดึงรายการสินค้าของทุกออเดอร์ในคำสั่งเดียว ทำแบบนี้กับข้อมูลทุกประเภท
ผลคือจำนวนคำสั่งไม่ขึ้นกับจำนวนการ์ดอีกต่อไป
ผลลัพธ์
| คำสั่งไปฐานข้อมูลต่อหน้า | 250+ → ไม่เกิน 7 |
| เวลาโหลด 50 การ์ด | 0.11 วินาที |
และเพราะจำนวนคำสั่งคงที่ หน้านี้จะไม่ช้าลงอีกแม้จะเพิ่มจำนวนรายการต่อหน้าในอนาคต
ผลพลอยได้ที่ไม่ได้ตั้งใจ
การบังคับให้เตรียมข้อมูลไว้ล่วงหน้าทำให้เกิดผลข้างเคียงที่ดีสองอย่าง
อย่างแรก — การ์ดกลายเป็นชิ้นส่วนที่ทดสอบได้ เพราะมันไม่ยุ่งกับฐานข้อมูลแล้ว ป้อนข้อมูลเข้าไปแล้วตรวจผลลัพธ์ได้ตรง ๆ
อย่างที่สอง — เราใช้การ์ดใบเดียวกันได้ทุกหน้า ตอนนี้หน้ารายการออเดอร์ หน้างานค้างส่ง และหน้าเปิดใบกำกับภาษี ใช้การ์ดตัวเดียวกันหมด ข้อมูลที่แสดงจึงตรงกันเสมอ และการเพิ่มข้อมูลลงการ์ดทำที่เดียวมีผลทุกหน้า
ก่อนหน้านี้แต่ละหน้ามีการ์ดของตัวเองที่แสดงข้อมูลไม่เท่ากัน ซึ่งทำให้ผู้ใช้สับสนว่าทำไมหน้าหนึ่งเห็นข้อมูลที่อีกหน้าไม่เห็น
ข้อแลกเปลี่ยนที่เรายอมรับ
กฎนี้มีต้นทุน — การเพิ่มข้อมูลลงการ์ดยุ่งยากกว่าเดิม เพราะต้องไปแก้ตัวประกอบข้อมูลด้วย ไม่ใช่แก้ที่การ์ดจุดเดียวจบ
เรายอมรับต้นทุนนี้ เพราะความยุ่งยากตกอยู่กับคนเขียนโค้ด ครั้งเดียว ในขณะที่ความช้าตกอยู่กับผู้ใช้ ทุกครั้งที่เปิดหน้า
เราเขียนกฎนี้ไว้ในเอกสารมาตรฐานของทีมพร้อมเหตุผล เพื่อให้คนที่มาทีหลังรู้ว่าทำไมต้องลำบากกว่า — เพราะกฎที่ไม่มีเหตุผลกำกับจะถูกยกเลิกโดยคนถัดไปเสมอ
บริหารจัดการข้อมูลในองค์กร ครบในที่เดียว