สร้างเว็บไซต์สแตติกด้วยตัวเอง: JAMstack, เวลาบิลด์, การดีพลอยบน CDN และ SEO
1. JAMstack แก้ปัญหาอะไรกันแน่
ตัวอักษรสามตัวของ JAMstack ย่อมาจาก JavaScript, API และ Markup สถาปัตยกรรมแบบดั้งเดิมคือ “ผู้ใช้ร้องขอ → เซิร์ฟเวอร์รันคิวรีฐานข้อมูล → เรนเดอร์ HTML → ส่งกลับ” ซึ่งทุกขั้นตอนใช้เวลา JAMstack ย้ายสามขั้นตอนนี้มาทำล่วงหน้าตอนบิลด์ พอดีพลอยก็โยนไฟล์ HTML ที่สร้างเสร็จแล้วไปที่ CDN ทั่วโลก เมื่อผู้ใช้เข้าถึง CDN จะส่งไฟล์กลับทันทีโดยไม่ผ่านแบ็กเอนด์ใด ๆ
ข้อสรุปที่ขัดกับสัญชาตญาณ: ผลตอบแทนที่ใหญ่ที่สุดของ JAMstack ไม่ใช่ความปลอดภัยหรือต้นทุน แต่คือ SEO และความเร็วในการแสดงผลครั้งแรก หน้าที่สร้างแบบไดนามิกจากฐานข้อมูลมักมี TTFB อยู่ที่ 300 ถึง 800 มิลลิวินาที และยังต้องรอ JavaScript ดาวน์โหลดและทำงาน ส่วน HTML สแตติกที่ CDN ส่งกลับโดยตรงมักมี TTFB ต่ำกว่า 100 มิลลิวินาที และบอทได้เนื้อหาที่เรนเดอร์ครบถ้วนแล้ว วิธีวัด Core Web Vitals ดูได้ที่การปรับแต่ง Core Web Vitals。
แต่สแตติกไม่ได้แปลว่า “ขยับไม่ได้” ส่วนที่ต้องมีปฏิสัมพันธ์บนหน้า (ฟอร์มสอบถาม สต็อกแบบเรียลไทม์ แปลงอัตราแลกเปลี่ยน) ใช้ JavaScript เรียก API ทำงานฝั่งเบราว์เซอร์ ไม่กระทบการแจกจ่าย HTML แบบสแตติก นี่คือความหมายของ “เติมความไดนามิกด้วย API” วิธีเลือก CDN ดูได้ที่CDN เร่งความเร็วทั่วโลก。
| ประเภทสถาปัตยกรรม | TTFB | เนื้อหาที่บอทได้รับ | ค่าดูแลเซิร์ฟเวอร์ (ต่อเดือน) | เหมาะกับประเภทหน้า |
|---|---|---|---|---|
| HTML สแตติก + CDN | 50 ถึง 100 มิลลิวินาที | HTML ที่เรนเดอร์ครบถ้วน | 0 ถึง 50 หยวน | บทความ รายละเอียดสินค้า หน้า About |
| SSG + ISR (Next.js) | 100 ถึง 300 มิลลิวินาที | HTML ครบถ้วน | 200 ถึง 800 หยวน | บทความ + หน้ารายการที่ต้องรีเฟรชเป็นระยะ |
| SSR เรนเดอร์แบบไดนามิก | 300 ถึง 800 มิลลิวินาที | ต้องรอเรนเดอร์ | 1,000 ถึง 5,000 หยวน | หน้าเฉพาะบุคคล หน้าข้อมูลเรียลไทม์ |
| SPA เรนเดอร์ฝั่งฟรอนต์เอนด์ล้วน | 20 ถึง 50 มิลลิวินาที (เปลือกเปล่า) | HTML ว่างเปล่า + JS | 0 ถึง 200 หยวน | ระบบหลังบ้าน ไม่เหมาะกับหน้าโปรโมท |
2. เวลาบิลด์: คอขวดแรกเมื่อหน้าเยอะขึ้น
ตอนหน้าเว็บยังน้อย เวลาบิลด์ไม่ใช่ปัญหา Hugo บิลด์ 50 หน้าใช้เวลาแค่ไม่กี่วินาที แต่พอเกิน 500 หน้า ช่องว่างของเวลาบิลด์ระหว่างเฟรมเวิร์กต่างๆ เริ่มชัดขึ้น Hugo ยังคงไม่เกิน 30 วินาที Next.js อาจใช้ 3 ถึง 5 นาที ส่วน Gatsby เกิน 10 นาทีไปเลย เวลาบิลด์ส่งผลโดยตรงกับสองเรื่อง คือเวลารอให้เนื้อหาขึ้นออนไลน์ กับประสบการณ์การพัฒนา ที่แค่แก้คำผิดคำเดียวยังต้องรอหลายนาที
กรณีที่หนึ่ง: บล็อก B2B ที่สะสมบทความมา 300 ชิ้นในสองปี ใช้ Next.js บิลด์ ทุกครั้งที่แก้หัวข้อบทความหนึ่งชิ้น ต้องบิลด์ใหม่ทั้งหมด 4 นาที ทีมเริ่มไม่อยากแก้เนื้อหาบ่อยๆ วิธีแก้คือเปิดใช้ Incremental Static Regeneration (ISR) ของ Next.js หรือเปลี่ยนไปใช้แคชระดับเนื้อหา ให้รีบิลด์เฉพาะเส้นทางที่ได้รับผลกระทบ เวลาบิลด์ลดจาก 4 นาทีเหลือ 20 วินาที
กรณีที่สอง: เว็บแคตตาล็อกสินค้าที่มี 2,000 SKU แต่ละ SKU มีหน้าดีเทลหนึ่งหน้า บิลด์ Next.js แบบเต็มใช้เวลา 12 นาที ตั้งบิลด์อัตโนมัติวันละครั้ง ขนาดนี้แนะนำให้เปลี่ยนไปใช้ Hugo หรือ Eleventy เลย จะกดเวลาบิลด์ให้เหลือไม่ถึง 1 นาทีได้ วิธีบีบอัดรูปเป็นชุด ดูที่SEO รูปภาพและ WebP。
| จำนวนหน้า | เวลาบิลด์ Hugo | เวลาบิลด์ Next.js SSG | แนวทางที่แนะนำ |
|---|---|---|---|
| น้อยกว่า 100 หน้า | 2 ถึง 5 วินาที | 30 ถึง 60 วินาที | เลือกอะไรก็ได้ ประสบการณ์ต่างกันไม่มาก |
| 100 ถึง 500 หน้า | 5 ถึง 20 วินาที | 1 ถึง 3 นาที | Next.js รับได้ เปิด incremental build |
| 500 ถึง 2,000 หน้า | 20 ถึง 60 วินาที | 3 ถึง 8 นาที | เลือก Hugo ก่อน ถ้าใช้ Next.js ต้องปรับแต่งหนัก |
| เกิน 2,000 หน้า | 1 ถึง 3 นาที | เกิน 10 นาที | ต้องใช้ Hugo หรือบิลด์แบบแบ่งส่วน |
สาม、การ deploy ผ่าน CDN: จากตอน commit ถึงใช้งานได้ทั่วโลกใช้เวลานานแค่ไหน
ขั้นตอน deploy ของ JAMstack ง่ายมาก: git push → แพลตฟอร์มบิลด์อัตโนมัติ → สร้างไฟล์ static → push ไปยังโหนด CDN ทั่วโลก Vercel และ Netlify รองรับ Next.js และ Eleventy แบบ native ส่วน Cloudflare Pages รองรับ Hugo และไฟล์ static ล้วนได้ดี เวลา deploy ตั้งแต่ commit จนเข้าถึงได้ทั่วโลก ปกติอยู่ระหว่าง 30 วินาทีถึง 3 นาที
ตรงนี้มีกับดักที่เจอง่าย: แคช CDN หมดอายุช้า ถ้าคุณแก้ราคาสินค้าแล้ว deploy ใหม่ บาง edge node อาจยังแคชเวอร์ชันเก่าอยู่ นานสุดอาจเก็บไว้ถึง 24 ชั่วโมง วิธีแก้คือหลัง deploy เสร็จให้สั่ง refresh CDN แบบเต็ม หรือใส่ content hash ต่อท้าย URL (ชื่อไฟล์มี hash เช่น style.abc123.css) ไฟล์ใหม่จะแทนที่ไฟล์เก่าอัตโนมัติ วิธีตั้งค่าแคช ดูที่นโยบายแคชของเว็บไซต์。
ตัวอย่างจากสถานการณ์จริง: แบรนด์โคมไฟที่ออกตลาดต่างประเทศใช้ Next.js SSG หน้าสินค้า 200 หน้า บิลด์เต็มใช้เวลา 3 นาที เพื่อนร่วมทีมการตลาดแก้รูปสินค้าหนึ่งรูป หลัง commit โค้ดต้องรอ 3 นาทีให้บิลด์เสร็จ แล้วรออีก 1 นาทีให้ CDN อัปเดต ผู้ใช้ถึงจะเห็นรูปใหม่ ต่อมาเปิดใช้ ISR ตั้งค่า revalidate ทุก 60 วินาทีต่อหน้า หลังแก้รูป ผู้ใช้เห็นเวอร์ชันใหม่เร็วสุดใน 60 วินาที และเวลาบิลด์ก็ลดจาก 3 นาทีเหลือ 40 วินาที
| แพลตฟอร์ม deploy | โควตาฟรี | จำนวนโหนดทั่วโลก | ข้อจำกัดเวลาบิลด์ | เหมาะกับสถานการณ์ |
|---|---|---|---|---|
| Vercel | แบนด์วิดท์ 100GB/เดือน | 300+ | 6 นาที/ครั้ง | โปรเจกต์ Next.js ทีมทำงานร่วมกัน |
| Netlify | แบนด์วิดท์ 100GB/เดือน | 100+ | 30 นาที/ครั้ง | Hugo/Eleventy ฟังก์ชันฟอร์ม |
| Cloudflare Pages | แบนด์วิดท์ไม่จำกัด | 300+ | ไม่มีเพดานตายตัว | จำนวนหน้าสูง ต้นทุนอ่อนไหว |
| โฮสต์เอง + Cloudflare CDN | CDN ฟรี ส่วนต้นทางคิดแยก | 300+ | ควบคุมเองได้ทั้งหมด | ต้องเขียน build pipeline เอง |
สี่、มุมมอง SEO: ทำไมเว็บ static ได้เปรียบโดยธรรมชาติ
Googlebot เรนเดอร์ JavaScript ได้แล้ว แต่มีข้อจำกัดด้านเวลาและทรัพยากร ส่วน HTML แบบ static ส่งเนื้อหาครบตั้งแต่คำขอแรก บอทไม่ต้องรอ JS ทำงาน และไม่พลาดเนื้อหาเพราะ JS โหลดไม่สำเร็จ ข้อดีตรง ๆ ต่อ SEO คือ เก็บ index ได้เร็ว ข้อผิดพลาดจากการเรนเดอร์น้อยลง และ structured data ถูกอ่านเจอแน่นอน
อีกข้อดีคือ sitemap และโครงสร้าง URL สร้างได้ในครั้งเดียวตอน build ไม่ต้อง query ฐานข้อมูลแบบไดนามิก ชื่อไฟล์ ลำดับโฟลเดอร์ และ canonical tag เขียนตายไว้ในสคริปต์ build ได้เลย จึงไม่เจอปัญหาเนื้อหาซ้ำระหว่างหน้าป้ายกับหน้าโพสต์แบบที่เว็บไดนามิกเจอบ่อย วิธีปรับ sitemap ให้ดีขึ้น ดูที่ปรับ XML sitemap ให้ดีขึ้น。
แต่มีจุดที่สวนทางกับที่คิด: เว็บ static ไม่ได้ดีทุกตัวชี้วัด SEO ถ้าเนื้อหาอัปเดตบ่อย เช่น ราคาหรือสต็อกที่เปลี่ยนทุกวัน พอทำ static ข้อมูลจะกลายเป็นของเก่า ผู้ใช้เปิดหน้าแล้วเห็นราคาของ 24 ชั่วโมงก่อน อัตราตีกลับจะสูงขึ้น หน้าประเภทนี้ต้องดึงข้อมูลสดผ่าน API ฝั่ง client จะยัดลง HTML static ไม่ได้
ยังมีรายละเอียดที่ต้องระวัง: การจัดการรูปในเว็บ static WordPress สร้างรูปหลายขนาดให้อัตโนมัติเมื่ออัปโหลด แต่ Hugo กับ 11ty ต้องเขียนเองในสคริปต์ build ถ้าลืมขั้นตอนนี้ ผู้ใช้จะโหลดรูปต้นฉบับกว้าง 4000 พิกเซลมาดูบนมือถือ ทำให้ LCP พุ่งจาก 1.5 วินาทีเป็น 4 วินาที วิธีตั้งค่าบีบอัดรูปและแปลงฟอร์แมต ดูที่SEO รูปภาพและฟอร์แมต WebP。
| มิติ SEO | เว็บ static | เว็บไดนามิก | สาเหตุที่ต่างกัน |
|---|---|---|---|
| ความครบของเนื้อหาในหน้าจอแรกที่บอทเห็น | 100% | 60% ถึง 90% (ขึ้นกับว่า JS ทำงานแค่ไหน) | ไม่ต้องรอเรนเดอร์ |
| TTFB | 50 ถึง 100 มิลลิวินาที | 300 ถึง 800 มิลลิวินาที | ไม่มีการ query ฐานข้อมูล |
| LCP | 1.0 ถึง 1.8 วินาที | 2.0 ถึง 4.0 วินาที | CDN ส่งตรง + ไม่มีแบ็กเอนด์ |
| ความสดของเนื้อหา | ต่ำ (เป็นภาพนิ่งตอน build) | สูง (ได้ข้อมูลล่าสุดทุกคำขอ) | static เป็นดาบสองคม |
| ความน่าเชื่อถือของ structured data | 100% | 80% ถึง 95% | เขียนลง HTML ตอน build |
FAQ คำถามที่พบบ่อย
JAMstack ดีกว่า WordPress แบบเดิมตรงไหนในมุม SEO?
ถ้า build นานเกินไปทำไงดี อย่าง Next.js 500 หน้าที่ต้องรัน 8 นาที?
อัปเดตเนื้อหาของ static site ขึ้น CDN ยังไง ต้องล้าง cache เองไหม
หน้าแบบไหนไม่ควรทำ static
Hugo กับ Next.js SSG เลือกยังไง
deploy JAMstack ไปที่ Cloudflare Pages ต้องเสียเงินไหม
ทิ้งท้าย
JAMstack ไม่ใช่แนวคิดใหม่ แก่นแท้คือ “ทำทุกอย่างที่ทำล่วงหน้าได้ให้เสร็จก่อน” สำหรับ B2B standalone site ที่เน้นแสดงเนื้อหา สถาปัตยกรรมนี้ได้เปรียบทั้งด้าน performance ต้นทุน และ SEO พร้อมกัน แทบไม่มีเหตุผลให้ปฏิเสธ อุปสรรคเดียวคือทีมต้องยอมรับวิธีทำงานแบบ “สร้างตอน build” คือแก้เนื้อหาแล้วต้องรอ build ไม่เห็นผลทันทีเหมือน WordPress
คำแนะนำในการเริ่มต้นคือเริ่มจากสิ่งเล็กที่สุดที่ทำได้ก่อน: ย้ายส่วนบล็อกไปเป็น static site ด้วย Hugo หรือ Eleventy โดยไม่แตะเว็บหลัก WordPress เดิม ลองรันสักหนึ่งเดือน แล้วเทียบ LCP ความเร็วในการถูก index และค่าดูแลเซิร์ฟเวอร์ก่อนกับหลังย้าย ถ้าผลลัพธ์ชัดเจนว่าคุ้ม ค่อยทยอยย้ายหน้าสินค้าและหน้าแรกตามมา ข้อดีของการย้ายแบบค่อยเป็นค่อยไปคือย้อนกลับได้ทุกเมื่อ
ประโยคเดียวที่จำง่าย ๆ: จุดแข็งของ static site ไม่ได้อยู่ที่คำว่า “static” แต่อยู่ที่ “ทั้ง crawler และผู้ใช้ได้รับเนื้อหาครบถ้วนชุดเดียวกัน ณ เวลาเดียวกัน” ซึ่งในยุคที่เว็บเรนเดอร์แบบไดนามิก กลับกลายเป็นของหายาก
