เว็บไซต์แบรนด์กับ micro frontend: หลายทีมทำงานร่วมกัน แยกเทคโนโลยี และ deploy อิสระ
หนึ่ง micro frontend แก้ปัญหาอะไรกันแน่
micro frontend แยกแอป frontend หนึ่งตัวออกเป็นหลาย sub-app ตามโดเมนธุรกิจ แต่ละ sub-app พัฒนาและ deploy โดยทีมอิสระ แล้วมี “shell” (Shell) หนึ่งตัวคอยประกอบทั้งหมดเข้าไว้ในหน้าเดียวกัน เทียบได้กับ microservice ฝั่ง backend ที่แยกระบบใหญ่เป็นหลาย service แล้ว deploy แยกกัน ฝั่ง frontend ก็ทำแบบเดียวกันได้
ปัญหาที่มันแก้มีสามข้อชัดเจน ข้อแรก หลายทีมแก้โค้ดในโค้ดเบสเดียวกัน เกิด merge conflict บ่อยขึ้นเรื่อย ๆ ข้อสอง ทีม A อยากอัปเกรด React 19 แต่ทีม B ยังใช้ React 17 ต่างฝ่ายต่างถ่วงกัน ข้อสาม แก้เล็กน้อยต้อง build ทั้งเว็บและปล่อยทั้งเว็บ ทดสอบ regression ครอบคลุมทั้งไซต์ ความเสี่ยงสูงขึ้นเรื่อย ๆ ปัญหาทั้งสามข้อนี้มาจาก “ขนาดขององค์กร” ไม่ใช่เพราะความสามารถทางเทคนิคไม่พอ
ข้อสรุปที่ขัดกับสัญชาตญาณ: ประโยชน์ของ micro frontend เป็นสัดส่วนโดยตรงกับขนาดทีม ยิ่งทีมเล็ก ประโยชน์ติดลบของ micro frontend ยิ่งมาก ทีม frontend 3 คนที่แยก micro frontend เท่ากับเพิ่มความซับซ้อนอีกสามชั้นให้ตัวเอง ทั้ง shell application, การประสาน routing และการสื่อสารข้ามแอป ทั้งที่จริงพวกเขาไม่มีปัญหา merge conflict อยู่แล้ว จะเลือก tech stack ของ WordPress อย่างไร ดูที่การเลือกสแต็กเทคโนโลยี WordPress。
| ตัวชี้วัด | ไม่เหมาะกับ micro frontend | อาจพิจารณา micro frontend | ต้องใช้ micro frontend |
|---|---|---|---|
| จำนวนทีม frontend | 1 ทีม | 2 ทีม | 3 ทีมขึ้นไป |
| จำนวนบรรทัดในโค้ดเบส | น้อยกว่า 1 แสนบรรทัด | 1 แสนถึง 5 แสนบรรทัด | มากกว่า 5 แสนบรรทัด |
| ความต่างของจังหวะการปล่อยเวอร์ชัน | พร้อมกันสัปดาห์ละครั้ง | บางทีมอัปเดตรายเดือน | ผสมระหว่างรายสัปดาห์และรายวัน |
| ความขัดแย้งของเทคโนโลยี | เป็นหนึ่งเดียวทั้งหมด | ขัดแย้งเล็กน้อย | มีหลายเฟรมเวิร์กอยู่ร่วมกัน |
| รูปแบบผลิตภัณฑ์ | เว็บการตลาดล้วน | เว็บการตลาดและหลังบ้านแบบง่าย | เว็บการตลาดและ SaaS ซับซ้อนและหลังบ้าน |
| ความซับซ้อนในการ deploy | repo เดียว build เดียว | repo เดียว build หลายตัว | หลาย repo หลาย build |
สอง สามวิธีที่พบบ่อย จะเลือกแบบไหน
แบบแรกคือ Module Federation เป็นความสามารถที่ webpack 5 มีมาให้ในตัว แอปย่อยประกาศตอน build ว่าจะ expose module ใด แอปหลักโหลดตอน runtime ข้อดีคือผสานรวมได้แน่น ข้อเสียคือต้องจัดเวอร์ชัน webpack ให้ตรงกันและ debug ค่อนข้างซับซ้อน เหมาะกับทีม React/Next.js ที่ใช้ webpack อยู่แล้ว
วิธีที่สองคือ import-map + SystemJS ประกาศ URL ของแอปย่อยผ่านไฟล์ JSON ตอน runtime แล้วแอปหลักโหลดตามต้องการ ข้อดีคือแยกเทคโนโลยีออกจากกันได้สมบูรณ์ แอปย่อยจะเป็น React, Vue หรือ Svelte ก็เลือกได้ตามใจ ข้อเสียคือการแยกสไตล์ข้ามแอปและการประสาน routing ต้องจัดการเอง
วิธีที่สามคือ Monorepo + หลายแอปที่ build แยกกัน เช่นใช้ Nx หรือ Turborepo จัดการหลายแพ็กเกจย่อย โดยแต่ละแพ็กเกจ build และ deploy แยกกัน ข้อดีคือแชร์โค้ดได้สะดวก ข้อเสียคือ repo ยิ่งใหญ่ build ยิ่งช้า ไม่เหมาะกับทีมขนาดใหญ่ ส่วนระบบลิงก์ภายในจะสร้างอย่างไร ดูได้ที่ระบบลิงก์ภายใน。
| 方案 | ระดับการแยกเทคโนโลยี | ต้นทุนการเรียนรู้ | ความซับซ้อนในการ build | เหมาะกับขนาด |
|---|---|---|---|---|
| Module Federation (Webpack 5) | ปานกลาง (เฟรมเวิร์กหลักเดียวกัน) | 2 ถึง 3 สัปดาห์ | ปานกลาง | ทีม React 20 ถึง 50 คน |
| import-map + SystemJS | สูง (ผสมเฟรมเวิร์กได้) | 3 ถึง 4 สัปดาห์ | สูง | มีหลายเฟรมเวิร์ก 50 คนขึ้นไป |
| Monorepo + หลายแอป | ต่ำ (แชร์ dependency) | 1 ถึง 2 สัปดาห์ | ต่ำ | หลายทีมในเฟรมเวิร์กเดียวกัน 10 ถึง 30 คน |
| ไมโครฟรอนต์แบบ iframe | สูงมาก | ต่ำมาก | ต่ำ | รวมหน้าเว็บของบุคคลที่สามชั่วคราว |
สาม B2B เว็บไซต์อิสระแบบไหนที่ต้องใช้ไมโครฟรอนต์จริง ๆ
เว็บไซต์ B2B อิสระแบบการตลาดล้วน ๆ ที่มีแค่หน้าแรก หน้าสินค้า บล็อก เกี่ยวกับเรา และติดต่อเรา ไม่จำเป็นต้องใช้ไมโครฟรอนต์ เว็บแบบนี้มักมีโค้ดไม่เกิน 5 หมื่นบรรทัด คนเดียวก็ดูแลได้ไม่ยาก การแยกเป็นไมโครฟรอนต์มีแต่จะสร้างปัญหาให้ตัวเอง
สิ่งที่ต้องใช้จริงคือเว็บแบบสามในหนึ่ง ทั้งเว็บการตลาด พอร์ทัลลูกค้า และระบบหลังบ้านตัวแทนจำหน่าย อย่างแพลตฟอร์มอุตสาหกรรมที่ออกสู่ตลาดต่างประเทศ เนื้อหาเว็บไซต์ดูแลโดยทีมการตลาด (Next.js เน้น SEO) ระบบสั่งซื้อและตรวจสอบของลูกค้าดูแลโดยทีมผลิตภัณฑ์ (React เน้นการโต้ตอบ) และระบบจัดการตัวแทนจำหน่ายดูแลโดยทีมปฏิบัติการ (Vue เน้นเครื่องมือ) ทั้งสามทีมมีจังหวะการปล่อยเวอร์ชันต่างกัน ใช้เทคโนโลยีต่างกัน และมีโค้ดเกิน 1 แสนบรรทัดทั้งสามทีม ในกรณีนี้ไมโครฟรอนต์จะประกอบแอปย่อยทั้งสามเป็น route ต่าง ๆ ภายใต้โดเมนเดียวกัน แต่ละทีม deploy แยกกันได้โดยไม่กระทบกัน ส่วนการมอนิเตอร์เว็บไซต์จะทำงานร่วมกับหลายแอปอย่างไร ดูได้ที่การมอนิเตอร์และแจ้งเตือนเว็บไซต์。
ตัวอย่างตามสถานการณ์ บริษัท SaaS ที่ออกสู่ตลาดต่างประเทศใช้ Next.js ทำเว็บไซต์ และใช้ React+Redux ทำแดชบอร์ดผู้ใช้ เดิมสองแอป deploy อยู่คนละซับโดเมน ต่อมาพบว่าหลังผู้ใช้ล็อกอินแล้วกระโดดจากเว็บไซต์ไปแดชบอร์ดต้องข้ามโดเมน ประสบการณ์ขาดตอน จึงใช้ Module Federation รวมสองแอปเข้าเป็นแอปหลักเดียวกัน แถบนำทางเป็นแบบเดียวกัน สถานะล็อกอินแชร์กัน แต่ deploy แยกกัน แก้เว็บไซต์ไม่กระทบแดชบอร์ด แก้แดชบอร์ดไม่กระทบเว็บไซต์ ความถี่ในการปล่อยเวอร์ชันเปลี่ยนจากสัปดาห์ละครั้งเป็นวันละสองครั้ง
| ความท้าทาย | วิธีของแอปแบบโมโนลิธ | วิธีของไมโครฟรอนต์ | ประโยชน์ |
|---|---|---|---|
| ความถี่ในการปล่อยเวอร์ชัน | ทดสอบถดถอยทั้งหมด สัปดาห์ละครั้ง | ซับแอปปล่อยอิสระ วันละหลายครั้ง | 上线速度提升5至10倍 |
| อัปเกรดสแต็กเทคโนโลยี | อัปเกรดทั้งคลังพร้อมกัน ความเสี่ยงสูง | อัปเกรดซับแอปทีละตัว | รอบการอัปเกรดจากรายไตรมาสเหลือรายสัปดาห์ |
| การทำงานร่วมกันของทีม | รวมโค้ดในคลังเดียว เกิด conflict บ่อย | แยกคลังของใครของมัน กำหนดอินเทอร์เฟซร่วมกัน | conflict ในการ merge ลดลง 80% |
| ขอบเขตผลกระทบเมื่อเกิดปัญหา | บั๊กตัวเดียว เว็บล่มทั้งไซต์ | ซับแอปพังกระทบแค่บางส่วน | รัศมีระเบิดของปัญหาลดลง |
| การเริ่มงานของคนใหม่ | ต้องเข้าใจทั้งไซต์ | ดูแค่ซับแอปของตัวเอง | ระยะเวลาปรับตัวจาก 4 สัปดาห์เหลือ 1 สัปดาห์ |
สี่ กับดักที่พบบ่อยที่สุดใน micro frontend
กับดักแรก: สไตล์ตีกันเอง ซับแอปสองตัวใช้ Bootstrap เหมือนกัน พอโหลดเข้าหน้าเดียวกัน สไตล์ก็เละไปหมด วิธีแก้คือใช้ CSS namespace (ใส่ prefix ให้แต่ละซับแอป) หรือแยกด้วย Shadow DOM นี่ไม่ใช่ปัญหาทางเทคนิค แต่ต้องกำหนดมาตรฐานตั้งแต่ช่วงเริ่มต้นโปรเจกต์ ไม่งั้นแก้ทีหลังจะเจ็บมาก
กับดักที่สอง: การสื่อสารข้ามแอป ผู้ใช้กรอกฟอร์มในเว็บการตลาด แล้วอยากส่งข้อมูลไปยังแดชบอร์ดในศูนย์ผู้ใช้ ถ้าซับแอปสองตัวแยกกันโดยสมบูรณ์ การสื่อสารต้องอาศัย URL parameter หรือ localStorage พอข้อมูลเยอะก็เละ วิธีแก้คือวาง global state management (เช่น zustand) ไว้ในเชลล์แอป ซับแอปอ่านเขียนผ่านอินเทอร์เฟซที่ตกลงกันไว้ อย่าให้ซับแอปเรียกหากันโดยตรง
กับดักที่สาม: ประสิทธิภาพกระจัดกระจาย ซับแอปแต่ละตัวโหลด React คนละชุด ผู้ใช้โหลดหน้าเว็บก็ดาวน์โหลด React ถึงสามชุด ขนาด JS รวมพุ่งจาก 500KB เป็น 1.2MB วิธีแก้คือย้าย dependency ที่ใช้ร่วมกันอย่าง React, Vue ไปไว้ในเชลล์แอป ซับแอปอ้างอิงผ่าน shared scope ไม่ต้องแพ็กซ้ำ ส่วนสคริปต์ของบุคคลที่สามจะจัดการยังไง ดูที่การจัดการสคริปต์ของบุคคลที่สาม。
| หลุมพราง | อาการ | วิธีแก้ | มาตรการป้องกัน |
|---|---|---|---|
| สไตล์ตีกัน | ปุ่มของซับแอป A กลายเป็นสไตล์ของซับแอป B | CSS prefix หรือ Shadow DOM | กำหนดมาตรฐานสไตล์ตั้งแต่เริ่มโปรเจกต์ |
| แชร์ state กันวุ่นวาย | ส่งข้อมูลข้ามซับแอปแล้วหาย | เชลล์แอปจัดการ state รวมศูนย์ | ตกลงอินเทอร์เฟซและโครงสร้างข้อมูลที่แชร์ร่วมกัน |
| ขนาด JS ซ้ำซ้อน | ซับแอปแต่ละตัวแพ็กเฟรมเวิร์กคนละชุด | ยก dependency ที่ใช้ร่วมกันขึ้นไปที่เชลล์แอป | วิเคราะห์ bundle ซ้ำตอน build |
| route ไม่ซิงก์กัน | รีเฟรชซับแอปแล้วเจอ 404 | เชลล์แอปจัดการ route รวมศูนย์ | กำหนดกฎ route รวมไว้ที่เดียว |
| ดีบักยาก | error ขึ้นมาไม่รู้ว่ามาจากซับแอปไหน | monitor error รวมศูนย์ + ติดแท็กซับแอป | Sentry บวก tag ของซับแอป |
FAQ คำถามที่พบบ่อย
micro frontend ต่างจาก iframe ยังไง ใช้ iframe ตรงๆ ไม่ได้เหรอ
ทีมฟรอนต์เอนด์ 5 คน โค้ดเบส 8 หมื่นบรรทัด ควรแยกเป็นไมโครฟรอนต์เอนด์ไหม
ไมโครฟรอนต์เอนด์ทำให้ความเร็วโหลดหน้าแรกช้าลงไหม
เว็บ WordPress ทำไมโครฟรอนต์เอนด์ได้ไหม
ขั้นตอนการ deploy ไมโครฟรอนต์เอนด์ทำอย่างไร
ไมโครฟรอนต์เอนด์มีผลกับ SEO ไหม
ทิ้งท้าย
Micro Frontend เป็นการตัดสินใจเชิงสถาปัตยกรรมที่ขับเคลื่อนด้วยขนาดทีม ตอนทีมยังเล็กมันเป็นภาระ แต่พอทีมใหญ่ขึ้นมันคือทางออก จะแยกหรือไม่แยก อย่าดูตามกระแสเทคโนโลยี ให้ดูที่ปัญหาจริงของคุณตอนนี้: คุณต้องจัดการ merge conflict ทุกสัปดาห์หรือเปล่า? แก้แค่ข้อความนิดเดียวก็ยังต้อง regression ทั้งระบบหรือเปล่า? สองทีมติดขัดกันเพราะ tech stack ไม่ตรงกันหรือเปล่า? ถ้าตอบ “ใช่” สองข้อจากสามข้อ ค่อยคิดเรื่องแยก
คำแนะนำในการลงมือทำ เริ่มแยกจากจุดที่เจ็บที่สุดก่อน: แยก sub-app ที่ release บ่อยที่สุดออกมาก่อน (ปกติคือหน้า campaign การตลาด) ส่วนอื่นยังไม่ต้องแตะ ทำไปสามเดือนแล้วดูผลตอบแทน: ถ้า release แยกแล้วขึ้นเร็วจริง merge conflict ลดลงจริง ค่อยแยกตัวที่สอง อย่าเพิ่งแยกทั้งเว็บออกเป็นห้าหก sub-app ตั้งแต่แรก นั่นคือการขุดหลุมให้ตัวเอง
ประโยคที่จำง่ายๆ: Micro Frontend คือมีดผ่าตัดสำหรับ “ทีมใหญ่ที่แยกไม่ออก” ไม่ใช่ของประดับสำหรับ “เว็บเล็กที่ยังไม่โต” — ถ้าทีมยังไม่ถึงขนาดนั้น แยกไปก็แค่ทำให้เรื่องง่ายกลายเป็นเรื่องยาก
