Back to notes
mastery-frontend-nextjs
Featured

Advanced Filtering Architecture: วิธีทำระบบกรองสินค้าให้ลื่นไหลระดับ 60FPS

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

February 5, 20262 min read readNNexis by Seereen

🛑 1. The Performance Killer: "Re-rendering ทุกครั้งที่ติ๊กถูก"

ปัญหาใหญ่ของระบบ E-commerce คือเมื่อมีตัวกรอง (Filters) เยอะๆ ทุกครั้งที่ผู้ใช้คลิกเลือกสีหรือไซส์ แอปมักจะอาการค้างไปชั่วขณะ:

  • สาเหตุ: การจัดการ State ที่ไม่ดีทำให้ทุก Card สินค้าต้องโหลดใหม่ (Re-render) ทั้งที่ควรจะเปลี่ยนแค่ตัวเลขผลลัพธ์เท่านั้น

Senior Solution: เราต้องใช้หลักการ "Optimistic UI" ผสมกับ "URL-State Management" เพื่อให้ระบบทำงานได้รวดเร็วที่สุดครับ


💡 2. Real-Life Analogy: พนักงานเสิร์ฟที่ต้องเดินกลับไปถามเชฟทุกคำถาม

  • การกรองแบบแย่ (Standard State): ทุกครั้งที่คุณถามว่า "มีเมนูมังสวิรัติไหม" พนักงานต้องเดินกลับไปถามเชฟในครัว (API Call) แล้วคุณก็นั่งรอหน้าจืด
  • การกรองแบบ Senior (Dual Layer Filtering): พนักงานมีเมนูอยู่ในมือแล้ว (Local Cache/URL State) เขาสามารถบอกคุณได้ทันทีว่ามีอะไรบ้าง ในขณะที่เขาส่งสัญญาณบอกเชฟให้เตรียมอาหารไว้รอ (Prefetching)
  • บทสรุป: ผู้ใช้จะไม่รู้สึกถึงการรอ เพราะ UI ตอบสนองได้ทันที (Instant Feedback) ครับ

🚀 3. Execution Journey: ขั้นตอนการสร้าง Filter ระดับโปร (Impressa Style)

ในโปรเจกต์ Impressa Shop ผมใช้เทคนิคดังนี้เพื่อให้ UI ลื่นไหลที่สุด:

🛠 Step-by-step:

  1. URL as Single Source of Truth: เก็บค่า Filter ทั้งหมดไว้ใน Query Parameters (เช่น ?color=red&size=xl) เพื่อให้ผู้ใช้กด Back/Forward หรือส่ง Link ให้เพื่อนได้โดยที่ Filter ไม่หาย
  2. Debouncing & Throttling: เมื่อผู้ใช้พิมพ์ค้นหา เราจะไม่ยิง API ทุกตัวอักษร แต่จะรอให้เขาหยุดพิมพ์สัก 300ms ก่อนเริ่มค้นหาจริง
  3. Skeleton Screens: ในระหว่างที่ข้อมูลใหม่กำลังโหลด เราจะแสดง Layout เปล่าๆ (Skeletons) ที่มีขนาดเท่าเดิม เพื่อไม่ให้หน้าเว็บ "กระตุก" (Layout Shift) ซึ่งทำลายประสบการณ์การใช้งาน
  4. TanStack Query (Cache Layer): เมื่อผู้ใช้กดย้อนกลับไปใช้ Filter เดิม ข้อมูลจะถูกดึงจาก Cache ทันทีโดยไม่ต้องโหลดจาก Server ใหม่
HLJS TSX
// ✅ การใช้ useSearchParams ร่วมกับ Next.js เพื่อทำ URL-State Filtering
function ProductFilters() {
  const searchParams = useSearchParams();
  const router = useRouter();

  const handleFilterChange = (key, value) => {
    const params = new URLSearchParams(searchParams);
    params.set(key, value);
    router.push(`?${params.toString()}`, { scroll: false });
  };
  // ...
}

🪤 4. The Junior Trap: "useEffect มหาศาลเพื่อ Sync State"

จูเนียร์มักจะใช้ useEffect เพื่อรอดูว่า Filter ตัวไหนเปลี่ยนแล้วค่อยยิง API:

  • ปัญหา: มันควบคุมยากและมักเกิด Infinite Loop ได้ง่ายมาก (Race Condition)
  • ✅ การแก้ไข: จงทำให้ Filter เป็น Stateless ให้มากที่สุด โดยให้ค่าทุกอย่างไหลมาจาก URL เพียงที่เดียวครับ

⚖️ 5. The UX Matrix: เร็วอย่างเดียวไม่พอ ต้อง "รู้สึก" ว่าเร็วด้วย

เทคนิคความซับซ้อนผลลัพธ์ที่ได้ (UX)
Standard Map()ง่าย🐌 ช้าและกระตุกเมื่อข้อมูลเยอะ
Virtual Listปานกลาง🚀 แสดงผลลื่นไหลแม้มีสินค้าหมื่นชิ้น
Next.js Suspenseปานกลาง✨ ประสบการณ์โหลดที่ไม่น่าเบื่อ
Server Actions Filteringสูง💎 เร็วที่สุดเพราะงานหนักทำที่ Server

🎓 6. Senior Mindset Summary

การทำระบบ Filter คือบทพิสูจน์ฝีมือของ Frontend Developer ว่าใส่ใจเรื่อง Performance และ UX แค่ไหนครับ อย่าลืมว่าทุกมิลลิวินาทีที่ผู้ใช้ต้องรอ คือโอกาสที่เขาจะปิดหน้าเว็บหนีไปหาคู่แข่ง การเขียนโค้ดให้เร็วไม่ใช่แค่เรื่องของ Logic แต่คือการเข้าใจ User Behavior ครับ!

## References

Share this note

© 2026 My Notes by Seereen