
เป็นเวลาหลายปีที่ Vercel เป็นแพลตฟอร์มหลักที่เราใช้ดีพลอยแทบทุกอย่างบนเว็บของ WebCatalog โปรเจกต์ส่วนใหญ่ใช้ Next.js จึงเป็นคู่ที่ลงตัวโดยธรรมชาติ ทั้งเว็บไซต์การตลาด อินเทอร์เฟซผลิตภัณฑ์ การตั้งค่าบัญชี คอนโซลนักพัฒนา ระบบยืนยันตัวตน เครื่องมือแอดมิน และ API ต่างก็ใช้เทคโนโลยีชุดเดียวกันโดยประมาณ
แนวทางนี้ใช้ได้ดีมาเป็นเวลานาน Vercel ทำให้การดีพลอยเป็นเรื่องง่าย Next.js เป็นเฟรมเวิร์กฟูลสแต็กที่ช่วยให้เราทำงานได้รวดเร็ว และเราแทบไม่ต้องคิดถึงโครงสร้างพื้นฐานเบื้องหลังทั้งสองอย่าง
แต่ในที่สุด ความสะดวกนั้นก็ไม่สอดคล้องกับลักษณะผลิตภัณฑ์ของเราอีกต่อไป
เว็บไซต์การตลาดของเรายังคงได้ประโยชน์จาก SSR (การเรนเดอร์ฝั่งเซิร์ฟเวอร์) แต่เว็บแอปอื่น ๆ ส่วนใหญ่ไม่จำเป็นต้องใช้ มันสามารถเป็น SPA (แอปพลิเคชันหน้าเดียว) ธรรมดาได้ ส่วน API ต้องการสภาพแวดล้อม Node.js ปกติที่รองรับไลบรารีแบบเนทีฟและโพรเซสที่ทำงานต่อเนื่อง ขณะที่แทบทุกอย่างในชุดเทคโนโลยีฟรอนต์เอนด์ของเราใช้ Vite อยู่แล้ว ในเวลาเดียวกัน ต้นทุนโครงสร้างพื้นฐานก็เริ่มเป็นสิ่งที่มองข้ามได้ยาก โดยเฉพาะเมื่อทราฟฟิกจากผู้ใช้ทั่วไปและระบบอัตโนมัติเพิ่มขึ้น
ตอนแรกเราพยายามปรับปรุงสิ่งที่มีอยู่ เราพิจารณาคง Next.js ไว้แล้วใช้ตัวปรับให้ทำงานบน Cloudflare Workers เราลองใช้ Astro กับเว็บไซต์การตลาด และเคยย้าย API ไปไว้บน Cloudflare Containers ช่วงสั้น ๆ
สุดท้ายเรามาจบที่แนวทางที่เรียบง่ายกว่า: เว็บแอปส่วนใหญ่ใช้ Vite + TanStack Router บน Cloudflare Workers เว็บไซต์การตลาดใช้ TanStack Start พร้อม SSR บน Cloudflare Workers และ API ใช้ Hono + tRPC บน Railway ในรูปแบบคอนเทนเนอร์ Node.js ที่ทำงานต่อเนื่อง
การย้ายระบบช่วยลดต้นทุนโครงสร้างพื้นฐานเว็บของเราได้ประมาณ 80% หลังจากเราปรับกฎความปลอดภัยของ Cloudflare ให้เข้มงวดขึ้นและบล็อกทราฟฟิกอัตโนมัติที่เป็นภัยมากขึ้นที่เอดจ์ ยอดประหยัดรวมก็เพิ่มเป็นประมาณ 90%
งานติดตั้งและย้ายระบบส่วนใหญ่ดำเนินการโดยเอเจนต์เขียนโค้ด AI ซึ่งหลัก ๆ คือ Claude Fable 5 และ Claude Opus 5 ส่วนวิศวกรเป็นผู้ตัดสินใจด้านสถาปัตยกรรม กำหนดข้อจำกัด ตรวจทานการเปลี่ยนแปลง และยืนยันผลลัพธ์
เราไม่ได้เริ่มจากการเลิกใช้ Vercel
สัญชาตญาณแรกของเราคือปรับปรุงระบบเดิม
webcatalog.io เป็นจุดเริ่มต้นที่ชัดเจนที่สุด เพราะมีทราฟฟิกสาธารณะจำนวนมาก แต่หน้าเว็บส่วนใหญ่เปลี่ยนไม่บ่อยนัก เราพบว่าหน้าเว็บจำนวนมากเกินไปยังถูกเรนเดอร์แบบไดนามิก เราจึงแก้การเรนเดอร์แบบไดนามิกที่เกิดขึ้นโดยไม่ตั้งใจ เพิ่ม ISR (Incremental Static Regeneration) ให้กับเส้นทางที่มีทราฟฟิกสูง ทำให้หน้าเว็บแคชได้มากขึ้น และปรับพฤติกรรมการสร้าง sitemap ที่ใช้ทรัพยากรมาก
งานเหล่านั้นช่วยได้ แต่ก็ทำให้ปัญหาพื้นฐานชัดขึ้นด้วย เราใช้เวลามากขึ้นเรื่อย ๆ เพื่อทำความเข้าใจว่าทำไมเนื้อหาที่ค่อนข้างคงที่จึงกลายเป็นไดนามิก พฤติกรรมใดของเฟรมเวิร์กที่ทำให้เป็นเช่นนั้น และต้องใช้กลไกใดของเฟรมเวิร์กเพื่อให้แคชได้อีกครั้ง
ขณะเดียวกัน แอปพลิเคชันอื่น ๆ ของเรากลับมีปัญหาตรงกันข้าม การตั้งค่าบัญชี คอนโซลนักพัฒนา แอปแอดมิน และอินเทอร์เฟซผลิตภัณฑ์ส่วนใหญ่ไม่จำเป็นต้องเรนเดอร์บนเซิร์ฟเวอร์เลย ทั้งหมดเป็นแอปพลิเคชันในเบราว์เซอร์ที่สื่อสารกับ API
ณ จุดนั้น คำถามเปลี่ยนจาก “เราจะลดค่าใช้จ่าย Vercel ได้อย่างไร?” เป็น “ถ้าแอปพลิเคชันเหล่านี้ไม่ได้สร้างด้วย Next.js อยู่แล้ว เราจะสร้างมันอย่างไร?”
เราพิจารณาใช้ Next.js บน Cloudflare
ทางเลือกที่กระทบระบบเดิมน้อยที่สุดคือคง Next.js ไว้ แล้วย้ายจาก Vercel ไป Cloudflare Workers
เราพิจารณาทางเลือกนี้อย่างจริงจัง เพราะ Next.js สามารถทำงานบน Cloudflare ผ่านชั้นตัวปรับได้ ซึ่งจะช่วยให้เราคงโครงสร้างแอปพลิเคชันเดิมไว้ได้มาก
แต่เราไม่ได้มองว่า Next.js บน Cloudflare เทียบเท่ากับ Next.js บน Vercel เพราะ Next.js ผสานเข้ากับรันไทม์ ระบบดีพลอย พฤติกรรมการแคช และฟีเจอร์แพลตฟอร์มของ Vercel อย่างแนบแน่นที่สุด เมื่ออยู่บน Cloudflare ตัวปรับต้องแปลงสมมติฐานเหล่านั้นให้เข้ากับรันไทม์อีกแบบ
วิธีนี้อาจใช้ได้ดี แต่หากเป้าหมายของเราคือทำให้ชุดเทคโนโลยีเรียบง่ายขึ้น การเพิ่มชั้นความเข้ากันได้อีกชั้นก็ดูไม่เหมาะนัก
ยังมีประเด็นเรื่องเครื่องมือในภาพรวมด้วย แทบทุกอย่างที่เราสร้างในฝั่งฟรอนต์เอนด์ใช้ Vite อยู่แล้ว ไม่ว่าจะเป็นแอปเดสก์ท็อป ส่วนขยายเบราว์เซอร์ SPA หรือโปรเจกต์ฝั่งไคลเอนต์อื่น ๆ
Next.js หันไปใช้ Turbopack อย่างมาก และ Turbopack ก็พัฒนาขึ้นมาก นี่ไม่ใช่ข้อร้องเรียนเรื่องประสิทธิภาพ สำหรับเรา ความต่างที่สำคัญกว่าคือระบบนิเวศ Vite เป็นรากฐานร่วมของโค้ดฟรอนต์เอนด์ส่วนใหญ่อยู่แล้ว มีระบบนิเวศปลั๊กอินที่กว้างกว่า และใช้การตั้งค่าร่วมกันระหว่างโปรเจกต์ได้มากกว่า
ดังนั้น การคง Next.js ไว้บน Cloudflare อาจแก้ปัญหาโฮสติ้งได้บางส่วน แต่จะยังคงความไม่ลงตัวของเฟรมเวิร์กและระบบนิเวศเครื่องมือบิลด์ที่แยกต่างหากไว้
เราจึงถอยออกมาดูว่าแต่ละงานต้องการอะไรจริง ๆ
เราแยกชุดเทคโนโลยีตามลักษณะงาน
เมื่อเราเลิกมองหาสิ่งเดียวที่จะมาแทน Next.js ได้ทุกกรณี สถาปัตยกรรมก็เรียบง่ายขึ้นมาก
เว็บไซต์การตลาดต้องใช้ SSR เพราะมีหน้าสาธารณะหลายภาษา เมทาดาทา canonical URL, sitemap และทราฟฟิกจากเครื่องมือค้นหา
เว็บแอปอื่น ๆ ส่วนใหญ่ไม่ต้องใช้ SSR และสามารถเป็นแอป Vite ที่ใช้ TanStack Router ได้เลย
API ไม่จำเป็นต้องใช้เฟรมเวิร์ก React และเหมาะกับรันไทม์ Node.js ปกติมากกว่า
สุดท้ายเราแบ่งระบบดังนี้:
เว็บแอป
Vite + TanStack Router
│
└── Cloudflare Workers
เว็บไซต์การตลาด
TanStack Start + SSR
│
└── Cloudflare Workers
API
Hono + tRPC
│
└── Railway / คอนเทนเนอร์ Node.js
หลักการจึงตรงไปตรงมา: ใช้ SSR เมื่อมีประโยชน์จริง ใช้ SPA ธรรมดาเมื่อไม่จำเป็นต้องใช้ SSR และรันบริการแบ็กเอนด์บนรันไทม์สำหรับแบ็กเอนด์
เว็บแอปส่วนใหญ่กลายเป็น SPA
การย้ายไปเป็น SPA เป็นส่วนที่ง่ายที่สุด
เว็บแอป WebCatalog ย้ายได้รวดเร็วเป็นพิเศษ: เราสร้างโครงแอปใหม่ด้วย Vite + TanStack Router ย้ายอินเทอร์เฟซ เปลี่ยนการดีพลอยไปเป็น Cloudflare Workers และลบเวอร์ชัน Next.js เดิม ทั้งหมดภายในเช้าวันเดียว
เราทำแบบเดียวกันกับเว็บแอป Lexibird การตั้งค่าบัญชี คอนโซลนักพัฒนา ระบบยืนยันตัวตน และแอปแอดมิน นับจากเริ่มสร้างโครง SPA แรกจนลบแอปพลิเคชัน Next.js ตัวสุดท้ายใช้เวลาประมาณ 19 วัน
สำหรับแอปเหล่านี้ เราตั้งใจให้การทำงานบน Cloudflare Workers เรียบง่ายที่สุด Vite บิลด์ไฟล์สแตติก Cloudflare ให้บริการไฟล์เหล่านั้น และเส้นทางของแอปพลิเคชันที่ไม่ตรงกับไฟล์ใดก็จะกลับไปใช้ index.html ไม่มีรันไทม์ SSR เพราะไม่มีอะไรต้องเรนเดอร์บนเซิร์ฟเวอร์
ส่วนที่ยากกว่าคือการรักษาพฤติกรรมที่สะสมอยู่รอบแอปเหล่านี้ตลอดมา ตรรกะการยืนยันตัวตนบางส่วนต้องย้ายออกจากเส้นทางฝั่งเซิร์ฟเวอร์ของ Next.js ไปอยู่ใน API และแอปเดสก์ท็อป WebCatalog เวอร์ชันเก่ายังพึ่งพา endpoint เดิมที่เราต้องทำให้ใช้งานต่อไปได้
การย้าย UI ที่เขียนด้วย React นั้นง่าย
การรักษาข้อตกลงการทำงานเดิมยากกว่า
เราลอง Astro แล้วลบทิ้งในอีกห้าวันต่อมา
เว็บไซต์การตลาดย้ายยากกว่า
ตัวเลือกแรกของเราคือ Astro ซึ่งดูเหมาะกับ webcatalog.io และ lexibird.com โดยธรรมชาติ เพราะทั้งคู่เป็นเว็บไซต์สาธารณะที่มีเนื้อหามาก และ Astro ก็ทำงานร่วมกับ Cloudflare ได้ดี
เราเริ่มย้ายทั้งสองเว็บไซต์ แต่ห้าวันต่อมาก็หยุด
ไม่ได้มีข้อบกพร่องร้ายแรงเพียงข้อเดียว แต่มีความไม่ลงตัวเล็ก ๆ สะสมเพิ่มขึ้นเรื่อย ๆ บางเส้นทางต้องเข้าถึงฐานข้อมูลระหว่างการ prerender ขณะที่เราตั้งใจไม่ให้สภาพแวดล้อมสำหรับบิลด์มีข้อมูลรับรองฐานข้อมูลโปรดักชัน React islands ทำให้การแชร์สถานะของแอปพลิเคชันไม่เป็นธรรมชาติเท่าที่ควร เรายังพบความแตกต่างระหว่างเส้นทางที่ prerender ไว้กับเส้นทางที่เรนเดอร์ขณะทำงาน รวมถึงความติดขัดด้านเครื่องมือบางอย่างใน repository ของเรา
ไม่มีปัญหาใดแก้ไม่ได้ และนั่นเองที่ทำให้การทำต่อไปเสี่ยง เราอาจใช้เวลาอีกหลายสัปดาห์แก้ปัญหาทีละอย่างได้ง่าย ๆ
เราเลือกที่จะลบสิ่งที่ทำไว้แล้วเริ่มใหม่แทน
เอเจนต์ AI เปลี่ยนต้นทุนของการตัดสินใจครั้งนี้ งานย้ายโค้ดเชิงกลไกจำนวนมากไม่ได้กินเวลาหลายสัปดาห์ของวิศวกร ต้นทุนที่ลงไปแล้วจึงน้อยลง และการยอมรับว่าเราชอบสถาปัตยกรรมแบบอื่นก็ง่ายขายขึ้น
TanStack Start เหมาะกว่า
เราเริ่มย้ายเว็บไซต์การตลาดใหม่จากโค้ด Next.js ต้นฉบับ โดยคราวนี้ใช้ TanStack Start
มันเข้ากันได้เป็นธรรมชาติกว่ามาก เพราะเราใช้ TanStack Router ในแอป SPA อยู่แล้ว แนวคิดเรื่อง routing, loader, search parameter และ navigation จึงคล้ายกัน โค้ดยังคงเป็น React และ TypeScript ตามปกติ และระบบบิลด์ก็เป็น Vite
เราย้าย lexibird.com ไป TanStack Start ได้ภายในวันเดียว แล้วจึงย้าย webcatalog.io ตามมา
ข้อดีไม่ใช่ว่า TanStack Start แก้ทุกปัญหาได้อย่างมหัศจรรย์ แต่เป็นเพราะมันสอดคล้องกับทิศทางที่ชุดเทคโนโลยีส่วนอื่นของเรากำลังมุ่งไป
ใน monorepo เรื่องนี้สำคัญ การใช้เครื่องมือบิลด์ร่วมกันหมายถึงนำปลั๊กอินและการตั้งค่ากลับมาใช้ได้มากขึ้น มีกรณีพิเศษให้จัดการน้อยลงเวลาแก้บั๊ก นักพัฒนาต้องสลับบริบทน้อยลง และเอเจนต์เขียนโค้ดต้องเรียนรู้แนวปฏิบัติเฉพาะโปรเจกต์น้อยลง
Cloudflare ถูกกว่ามากสำหรับลักษณะทราฟฟิกของเรา
สถาปัตยกรรมเป็นเพียงส่วนหนึ่งที่ทำให้ค่าใช้จ่ายลดลง รูปแบบราคาของ Cloudflare เป็นปัจจัยสำคัญ โดยเฉพาะเรื่องแบนด์วิดท์
ปัจจุบัน Cloudflare Workers แพ็กเกจ Paid คิดค่าบริการหลัก ๆ ตามจำนวนคำขอและการใช้ CPU และ ไม่คิดค่าถ่ายโอนข้อมูลหรือค่าแบนด์วิดท์เพิ่มเติมสำหรับ Workers (developers.cloudflare.com) เรื่องนี้สำคัญมากสำหรับเว็บไซต์สาธารณะ เพราะคำขอหนึ่งอาจใช้ CPU เพียงเล็กน้อย แต่ยังต้องส่ง HTML, JavaScript, รูปภาพ ฟอนต์ และไฟล์อื่น ๆ
รูปแบบราคาของ Vercel มีหมวดการใช้งานและโควตาที่เกี่ยวข้องกับเครือข่ายด้วย รวมถึง Fast Data Transfer และ Fast Origin Transfer (vercel.com) สำหรับลักษณะทราฟฟิกของเรา Cloudflare คุ้มค่ากว่ามาก
การประหยัดไม่ได้มาจากการเปลี่ยนผู้ให้บริการอย่างเดียว เรายังย้ายแอปพลิเคชันจำนวนมากไปใช้ไฟล์สแตติกที่บิลด์ด้วย Vite ลด SSR ที่ไม่จำเป็น กำหนดการแคชให้ชัดเจนขึ้น และย้ายงาน API ไปยังรันไทม์ที่เหมาะสมกว่า แต่รูปแบบราคาของ Cloudflare โดยเฉพาะด้านแบนด์วิดท์ มีส่วนสำคัญต่อการลดต้นทุนได้ประมาณ 80% ที่เราพบ
ตัวเลขนี้เป็นผลจากลักษณะงานของเรา ไม่ได้หมายความว่าทุกแอปพลิเคชันที่ย้ายจาก Vercel ไป Cloudflare จะประหยัดได้ 80%
API ไปลงตัวที่ Railway
API เป็นอีกปัญหาหนึ่งที่แยกต่างหาก
แม้จะเป็นโปรเจกต์ Next.js แต่ API เหล่านี้แทบไม่ได้พึ่ง Next.js อยู่แล้ว WebCatalog API มีโค้ดประมาณ 34,000 บรรทัด แต่มีเพียงเจ็ดไฟล์ที่ import next/server ส่วน tRPC ก็ใช้ Fetch adapter อยู่แล้ว และ Inngest ก็รองรับ Hono
เราแทนส่วน HTTP ของ Next.js ด้วย Hono ซึ่งใช้แรงน้อยอย่างน่าประหลาดใจ
คำถามที่ยากกว่าคือจะรันที่ไหน Workers แบบปกติไม่เหมาะ เพราะ API ใช้ Node.js และไลบรารีแบบเนทีฟ เช่น sharp
ตอนแรกเราลอง Cloudflare Containers ซึ่งช่วยให้เราออกจาก Vercel ได้อย่างรวดเร็ว แต่หลังจากใช้งานบนโปรดักชัน เราพบว่ารูปแบบการดูแลระบบต้องปรับขนาดความจุด้วยตัวเองมากกว่าที่เราต้องการในตอนนั้น
เราจึงย้าย API อีกครั้ง
ปัจจุบัน API ทำงานบน Railway ในรูปแบบบริการคอนเทนเนอร์ Node.js ปกติที่รันต่อเนื่อง ระบบ CI (continuous integration) บิลด์ Docker image แล้วส่งขึ้น registry ของเรา ส่วน Railway จัดการปรับขนาดในแนวนอนอัตโนมัติ
ไม่ใช่ทุกอย่างต้องรันที่เอดจ์
การออกจาก Vercel หมายถึงต้องรับผิดชอบเองมากขึ้น
ต้นทุนที่ต่ำลงมีสิ่งที่ต้องแลก
เดิม Vercel และ Next.js จัดการพฤติกรรมด้านโครงสร้างพื้นฐานหลายอย่างให้ในระดับที่สูงกว่า เมื่อใช้ TanStack Start และ Workers เราหันมากำหนดการแคชผ่าน HTTP อย่างชัดเจนแทน เราเรนเดอร์หน้า ส่ง cache header กลับไป แล้วให้ Cloudflare แคชการตอบกลับนั้น การแคชในเบราว์เซอร์และที่เอดจ์สามารถใช้นโยบายต่างกันได้ รวมถึงพฤติกรรม stale-while-revalidate ที่เอดจ์
เราชอบที่ต้องตัดสินใจเรื่องเหล่านี้อย่างชัดเจน แต่เมื่อจัดการโครงสร้างพื้นฐานเองอย่างชัดเจน ความผิดพลาดก็เป็นความรับผิดชอบของเราเช่นกัน
เราพลาดไปบ้าง กฎแคชบนโปรดักชันข้อหนึ่งดันไปครอบคลุมการตอบกลับจาก server function ของ TanStack ที่เจาะจงผู้เข้าชมแต่ละคนโดยไม่ตั้งใจ และการตั้งค่าแคชอีกอย่างก็ทำงานร่วมกับพฤติกรรม SPA fallback ได้ไม่ดี บั๊กเหล่านี้เตือนเราว่าไม่อาจยืนยันความถูกต้องของการย้ายระบบจาก repository เพียงอย่างเดียว โครงสร้างพื้นฐานบนโปรดักชันก็เป็นส่วนหนึ่งของระบบด้วย
เอเจนต์ AI เปลี่ยนวิธีย้ายระบบของเรา
งานลงมือทำส่วนใหญ่ดำเนินการโดยเอเจนต์เขียนโค้ด โดยหลักคือ Claude Fable 5 และ Claude Opus 5
การย้ายเฟรมเวิร์กเป็นงานที่เหมาะกับเอเจนต์เป็นพิเศษ เพราะงานส่วนมากมีระบบเดิมเป็นตัวอ้างอิงที่ชัดเจน: ย้ายเส้นทางนี้ คง URL นี้ไว้ แทน API ของเฟรมเวิร์กตัวนี้ รักษาเมทาดาทาเดิม รัน typecheck แก้ข้อผิดพลาด แล้วเปรียบเทียบผลลัพธ์กับระบบเก่า
สำหรับ webcatalog.io เราทำตัวติดตามการย้ายระบบ โดยแบ่งงานเป็นช่วงต่าง ๆ เช่น วางรากฐาน หน้าผลิตภัณฑ์ หน้ารายการค้นหา การค้นหา บล็อก ราคา การเปลี่ยนเส้นทาง sitemap และการสลับไปใช้ระบบใหม่ แทนที่จะสั่งเอเจนต์ว่า “ย้าย webcatalog.io ไป TanStack Start” เรามอบหมายงานที่มีขอบเขตและเงื่อนไขที่ต้องรักษาไว้อย่างชัดเจน
แอปพลิเคชันเดิมกลายเป็นข้อกำหนดของงาน หน้าที่ของเอเจนต์คือสร้างพฤติกรรมเดิมขึ้นใหม่ด้วยสถาปัตยกรรมใหม่ ไม่ใช่ออกแบบผลิตภัณฑ์ใหม่
สิ่งนี้เปลี่ยนจุดที่มนุษย์ต้องลงแรง จากการแปลงโค้ดด้วยตัวเองไปสู่คำถามอย่าง: หน้านี้ควรใช้ SSR จริงหรือไม่? พฤติกรรมใดเกิดขึ้นโดยตั้งใจ? อะไรบ้างที่แคชร่วมกันทั่วระบบได้? URL ใดต้องเหมือนเดิมทุกประการ? ควรยืนยันตัวตนที่ไหน? และเมื่อใดควรหยุดพยายามทำให้แนวทางหนึ่งใช้ได้?
เรายังตรวจทานผลงาน รันบิลด์และ typecheck และตรวจสอบส่วนที่มีความเสี่ยงสูงด้วยตนเอง เช่น การยืนยันตัวตน SEO (การปรับแต่งเพื่อเครื่องมือค้นหา) การเปลี่ยนเส้นทาง และการแคช
การเปลี่ยนแปลงที่สำคัญไม่ใช่ AI เขียนโค้ดให้เรา แต่เป็นการที่ AI ทำให้การทดลองมีต้นทุนต่ำลง
การลอง Astro แล้วลบทิ้งหลังห้าวันกลายเป็นเรื่องที่ตัดสินใจได้ง่ายขึ้น การย้าย API หนหนึ่งแล้วตัดสินใจว่าอีกแพลตฟอร์มเหมาะกว่าก็เจ็บตัวน้อยลง เมื่องานเชิงกลไกมีต้นทุนต่ำลง เราจึงเปลี่ยนทิศทางได้เมื่อสถาปัตยกรรมไม่ถูกต้อง แทนที่จะฝืนทำต่อเพียงเพราะลงทุนไปมากแล้ว
เอเจนต์ทำให้กำลังในการลงมือพัฒนาไม่ใช่ทรัพยากรที่ขาดแคลนเหมือนเดิม
นั่นทำให้สถาปัตยกรรม ข้อจำกัด การตรวจทาน และการยืนยันผลลัพธ์สำคัญยิ่งขึ้น
จาก 80% กลายเป็นประมาณ 90%
หลังย้ายระบบ ต้นทุนโครงสร้างพื้นฐานเว็บของเราลดลงประมาณ 80%
จากนั้นเราก็เริ่มให้ความสำคัญมากขึ้นว่าคำขอใดเข้าถึงแอปพลิเคชันตั้งแต่แรก
ทราฟฟิกบนอินเทอร์เน็ตสาธารณะจำนวนไม่น้อยมาจากระบบอัตโนมัติ ไม่ว่าจะเป็นเครื่องมือค้นหา AI crawler เอเจนต์ เครื่องมือเก็บข้อมูล เครื่องมือสแกน และบอตที่ไม่เป็นมิตรนัก ทราฟฟิกบางส่วนมีประโยชน์ บางส่วนไม่มี
เมื่อแอปพลิเคชันอยู่หลัง Cloudflare โดยตรง เราจึงปรับกฎความปลอดภัยให้เข้มงวดขึ้น เพื่อปฏิเสธทราฟฟิกอัตโนมัติที่เป็นภัยตั้งแต่ที่เอดจ์ ก่อนที่จะกระตุ้นให้แอปพลิเคชันประมวลผลหรือเรียกใช้ฐานข้อมูล
หลังจากนั้น ยอดประหยัดรวมของเราก็เพิ่มเป็นประมาณ 90% เมื่อเทียบกับระบบเดิม
การลดต้นทุนทั้งหมดเกิดจากหลายปัจจัยร่วมกัน: ราคาของ Cloudflare ที่ต่ำกว่า โดยเฉพาะด้านแบนด์วิดท์; งานฝั่งเซิร์ฟเวอร์ที่ลดลง; รันไทม์ที่เหมาะกับ API มากขึ้น; การกำหนดการแคชที่ชัดเจนขึ้น; และการลดคำขอที่ไม่จำเป็นก่อนจะไปถึงแอปพลิเคชัน
จุดที่เรามาถึง
ใน repository ของเราไม่มีแอปพลิเคชัน Next.js เหลือแล้ว เว็บแอปส่วนใหญ่เป็น SPA ที่ใช้ Vite + TanStack Router บน Cloudflare Workers ส่วน webcatalog.io และ lexibird.com ใช้ TanStack Start บน Cloudflare Workers เพราะเว็บไซต์เหล่านี้ได้ประโยชน์จาก SSR จริง ๆ API ของเราใช้ Hono + tRPC บน Railway ทำงานเป็นคอนเทนเนอร์ Node.js ปกติ และโปรเจกต์ฟรอนต์เอนด์แทบทั้งหมดของเราก็อยู่ในระบบนิเวศของ Vite แล้ว
ต้นทุนโครงสร้างพื้นฐานของเราลดลงประมาณ 80% โดยความคุ้มค่าที่สูงกว่ามากของ Cloudflare สำหรับลักษณะทราฟฟิกของเรา โดยเฉพาะด้านแบนด์วิดท์ มีส่วนสำคัญอย่างยิ่ง การกรองทราฟฟิกอัตโนมัติที่เป็นภัยที่เอดจ์ช่วยดันยอดประหยัดรวมเป็นประมาณ 90%
แต่ผลลัพธ์ที่เราสนใจที่สุดคือเรื่องสถาปัตยกรรม เว็บไซต์การตลาดได้ใช้ SSR ส่วนอื่นที่เป็น SPA ได้ก็เป็น SPA และ API ก็ทำงานบนเซิร์ฟเวอร์จริงเมื่อเซิร์ฟเวอร์จริงเป็นทางเลือกที่เรียบง่ายกว่า
เราเริ่มจากการพยายามลดค่าใช้จ่าย Vercel
แต่จบลงด้วยการตระหนักว่าเราไม่จำเป็นต้องใช้สถาปัตยกรรมส่วนใหญ่ที่เราจ่ายเงินให้อยู่เลย