ทฤษฎีกับความเป็นจริงของ “เว็บไซต์แบบสแตติก”
(utcc.utoronto.ca)- ตรงข้ามกับมุมมองที่ว่าความแตกต่างระหว่างเว็บไซต์แบบสแตติกและไดนามิกเริ่มเลือนรางลง ในกรอบเวลาการดูแลระยะยาว เว็บไซต์ที่อิงไฟล์สแตติก ยังคงมีลักษณะที่แตกต่างออกไป
- วิธีการจัดวางไฟล์ที่สืบทอดมาตั้งแต่ยุคแรกของเว็บ และประสิทธิภาพของ การเสิร์ฟไฟล์สแตติก คือเหตุผลที่เว็บไซต์แบบสแตติกมักคงอยู่ได้นาน
- เว็บไซต์แบบสแตติกมี ขอบเขตความรับผิดชอบที่ชัดเจน อย่างไฟล์ซิสเต็มอยู่ระหว่างเว็บเซิร์ฟเวอร์กับเนื้อหา ทำให้สิ่งที่แต่ละฝ่ายต้องรู้เกี่ยวกับอีกฝ่ายมีจำกัด
- เว็บไซต์แบบไดนามิกทำให้ขอบเขตระหว่างเว็บเซิร์ฟเวอร์กับโค้ดของผู้ใช้เล็กและเรียบง่ายได้ยาก และยังยากที่จะ ทำให้ขอบเขตและ API นั้นเป็นมาตรฐานเดียวกัน
- เกณฑ์ในการแบ่งแยกไม่ได้อยู่ที่ปริมาณงานหรือความถี่ในการเปลี่ยนแปลง แต่อยู่ที่ว่าขอบเขตอยู่ตรงไหน และแต่ละฝ่ายต้องใส่ใจอะไรบ้าง
จุดเริ่มต้นของข้อถกเถียงเรื่องเว็บไซต์แบบสแตติก
- There is no such thing as a static website ของ Wesley Aptekar-Cassels มองว่าความแตกต่างระหว่างเว็บไซต์แบบสแตติกกับเว็บไซต์แบบไดนามิกนั้นน้อยกว่าที่คิด
- เว็บไซต์แบบสแตติกนั้น ไดนามิกและซับซ้อน กว่าที่ดูจากภายนอก
- การสร้างและดูแลเว็บไซต์แบบไดนามิกทำได้ง่ายกว่าในอดีต
- ประเด็นย่อยแต่ละข้อนำเสนอได้อย่างน่าเชื่อถือ แต่ไม่ได้พาไปถึงข้อสรุปว่าความแตกต่างระหว่างเว็บไซต์แบบสแตติกและไดนามิกลดลงแล้ว
ความแตกต่างที่เกิดจากความทนทานและขอบเขตความรับผิดชอบ
- ในกรอบเวลาระยะยาว เนื้อหาเว็บที่อิงไฟล์สแตติกได้แสดงให้เห็นถึง ความทนทาน สูงมาโดยตลอด
- แม้เว็บเซิร์ฟเวอร์และโฮสต์ที่ใช้จริงจะเปลี่ยนไป แต่วิธีจัดวางไฟล์ไว้ในไฟล์สแตติกและแผนผังไดเรกทอรียังคงสืบทอดมาตั้งแต่ยุคแรกของเว็บ
- การเสิร์ฟไฟล์สแตติกมักจำเป็นและมีประสิทธิภาพแม้ในเว็บไซต์แบบไดนามิก ดังนั้นเว็บไซต์ที่มีแต่ไฟล์สแตติกก็ใช้ประโยชน์จากข้อดีเดียวกันได้
- หากให้บริการเฉพาะเนื้อหาสแตติก ก็จะเป็นเว็บไซต์ที่มั่นคงและดูแลให้ทำงานต่อไปได้ง่าย ซึ่งในอดีตไม่ใช่สิ่งที่ใช้ได้กับเว็บไซต์แบบไดนามิก
- หัวใจของเว็บไซต์แบบสแตติกคือขอบเขตความรับผิดชอบที่มี การแยกส่วนที่เรียบง่ายและแข็งแรง
- ฝั่งหนึ่งมีความซับซ้อนของเว็บเซิร์ฟเวอร์สแตติก ซึ่งรวมถึงการอัปเดตแบบไดนามิกอย่างการต่ออายุใบรับรอง HTTPS
- อีกฝั่งหนึ่งมีไฟล์สแตติก และระหว่างสองฝั่งนั้นมีไฟล์ซิสเต็มหรือสิ่งที่คล้ายไฟล์ซิสเต็มวางอยู่
- สิ่งที่ทั้งสองฝั่งเรียกร้องจากกันและกันมีจำกัดมาก
- เว็บไซต์แบบไดนามิกยากที่จะมีขอบเขตเล็กและชัดเจนเช่นนี้ระหว่างเว็บเซิร์ฟเวอร์กับโค้ดของผู้ใช้
- โอกาสที่จะทำให้เป็นมาตรฐานด้วยขอบเขตเดียวและ API เดียวก็ต่ำ
- ในแง่หนึ่ง เว็บถูกออกแบบมาให้ให้บริการไฟล์สแตติก
- ความแตกต่างนี้ทำให้เว็บเซิร์ฟเวอร์สำหรับไฟล์สแตติกได้เปรียบด้านการดูแลและการย้ายระบบเมื่อเทียบกับเว็บเซิร์ฟเวอร์ไดนามิกและสภาพแวดล้อมรันไทม์
- เว็บเซิร์ฟเวอร์สำหรับไฟล์สแตติกหาได้ง่าย
- แม้ผู้ให้บริการปัจจุบันจะหยุดให้บริการ ก็ย้ายเว็บไซต์ไปที่อื่นได้ง่าย
- ความทนทานนี้ใช้ได้อย่างน้อยกับ เว็บไซต์สแตติกขนาดเล็กถึงกลาง ที่สามารถใส่ไว้ในเซิร์ฟเวอร์เดียวได้
- การแบ่งแยกระหว่างเว็บไซต์แบบสแตติกกับเว็บไซต์แบบไดนามิกไม่ได้เลือนราง
- เกณฑ์ไม่ใช่ปริมาณงานที่ต้องใช้ในการสร้างและดูแลเว็บไซต์ หรือปริมาณองค์ประกอบที่เปลี่ยนตามรอบเวลาอย่างการต่ออายุใบรับรอง HTTPS
- เกณฑ์คือขอบเขตอยู่ตรงไหน และแต่ละฝั่งต้องใส่ใจอะไร
- เว็บไซต์แบบสแตติกมีขอบเขตที่คมชัดซึ่งทำให้จัดการทั้งสองฝั่งได้อย่างเป็นอิสระ ส่วนเว็บไซต์แบบไดนามิกไม่มีขอบเขตแบบนั้นโดยธรรมชาติ จึงต้องขีดเส้นขึ้นมาเองหากจำเป็น
1 ความคิดเห็น
ความเห็นจาก Hacker News
ผมหาเลี้ยงชีพด้วยเว็บไซต์คอนเทนต์ และปีนี้ได้ย้ายจาก Craft CMS มาใช้ตัวสร้างเว็บไซต์แบบสแตติกที่ทำเอง
ตอนนี้ไม่ต้องคอยกังวลเรื่องเซิร์ฟเวอร์หรือ CMS แล้ว ไม่ต้องอัปเดต และยังตัดฐานข้อมูลขนาดใหญ่กับการตั้งค่าแคชที่ซับซ้อนออกไปได้ด้วย ตอนนี้มันเป็นแค่เซิร์ฟเวอร์ไฟล์แบบสแตติก จึงเสถียรกว่าและแทบไม่ต้องบำรุงรักษา
สิ่งที่ดีที่สุดคือทำงานแบบออฟไลน์ได้ แค่มีโปรแกรมแก้ไขข้อความก็พอ ทำให้แม้แต่ Macbook 12" เครื่องเล็กก็ยังรู้สึกเร็วมาก
การควบคุมเวอร์ชันก็มีประโยชน์มาก สามารถตรวจทานหรือย้อนการเปลี่ยนแปลงได้ และยังค้นหา/แทนที่ทั้งคอนเทนต์ด้วย regex ได้ด้วย ไฟล์ข้อความจัดการง่าย
ผมเขียนไว้ที่นี่ว่าการย้ายครั้งนี้ให้ความรู้สึกอย่างไรและทำไมมันถึงเวิร์ก: https://nicolasbouliane.com/projects/ursus
แต่ก็น่าจะดีถ้าเทคโนโลยีนี้เข้าถึงได้ง่ายขึ้นสำหรับคนที่ไม่มีความสามารถในการคอมไพล์และดีพลอยใหม่เอง มันเป็นวิธีสร้างเว็บไซต์ที่เร็วและถูก แต่เครื่องมือที่มีอยู่แล้วอย่าง Hugo มักตั้งสมมติฐานกับผู้ใช้ไว้เยอะพอสมควร จึงกลายเป็นอุปสรรคในการเริ่มต้น
อ่านบทความนี้แล้วสนุกดี ผมเป็นคนทำ html-to-markdown เวอร์ชันต้นฉบับที่ใช้ในการย้ายระบบด้วย ดีใจที่เห็นว่ายังมีคนใช้งานอยู่
เร็ว มีข้อมูลที่ต้องการครบ และไม่มีส่วนเกิน
ส่วนตัวอยากให้มีหมวดซีรีส์ทีวีกับภาพยนตร์ที่มี Berlin ในอดีตและปัจจุบันเป็นฉากหลัง พร้อมคะแนนสั้นๆ ว่าถ่ายทอด Berlin จริงได้สมจริงแค่ไหน
เป็นไปได้มากว่าเว็บไซต์กว่า 95% ทั้งหมด แค่แคชคอนเทนต์ยอดนิยม 70% ไว้ใน RAM แล้วให้อีก 30% เสิร์ฟจาก SSD ที่อ่านแบบสุ่มได้ 10,000 IOPS ก็เพียงพอแล้ว
ถ้าไม่ได้คอยนั่งปรับดีไซน์เว็บไซต์ตลอด การสร้างไซต์และ HTML ก็ควรทำบนเครื่องโลคัล และการสร้างทั้งชุดก็ควรใช้เวลาไม่ถึง 1 วินาที
แต่แนวทางที่ยึด GitHub, การควบคุมเวอร์ชัน, และโปรแกรมแก้ไขข้อความเป็นศูนย์กลาง ก็ยังเอนเอียงไปทางคนสายเทคนิคและโปรแกรมเมอร์อยู่ดี เราต้องการอะไรสักอย่างที่คล้าย WordPress แบบโฮสต์ หรือใกล้เคียงยุค Dreamweaver/Frontpage มากกว่า
ชอบตรงที่ถ้าอยากทำอะไรพิเศษก็สามารถลงลึกในรายละเอียดได้ ตัวอย่างเช่น ถ้าแก้บทความ Favorite Git Aliases มันสามารถแปลงเป็นไฟล์
.bash_aliasesแล้ว push ไปที่ GitLab และ mirror ไปที่ GitHub ได้ด้วยใครสนใจก็ดูได้ที่ https://jdsalaro.com ตอนนี้ยังไม่ได้เขียนเรื่องสแตกหรือเหตุผลไว้อย่างละเอียด แต่ตั้งใจจะค่อยๆ ทำเอกสารเพิ่ม
ตอนนี้เขียนไว้ก่อนแล้วเกี่ยวกับ Markdown สำหรับ Sphinx และชีตสรุป Myst (https://jdsalaro.com/cheatsheet/sphinx-myst-cheat-sheet/) รวมถึงวิธีโหลด
environment.pickle(https://jdsalaro.com/howto/sphinx-load-environment-pickle/)นี่หมายถึงการใช้ทรัพยากรอย่างไฟฟ้าน้อยลง ใช้ฮาร์ดแวร์ที่เล็กลงก็พอ และที่สำคัญที่สุดคือ ความปลอดภัย ดีขึ้น เว็บไซต์สแตติกโจมตีได้ยากกว่า และจุดบกพร่องที่เป็นไปได้ก็จำกัดอยู่ฝั่งเว็บเซิร์ฟเวอร์ ไม่ใช่โค้ดของเว็บไซต์
ปกติผมใช้ Hugo ซึ่งฟีเจอร์ครบมากและทำมาดีมาก เคยใช้ทำเว็บไซต์หลายภาษาแล้ว
การผสาน Turbo Hotwired เข้ากับเว็บไซต์สแตติกก็น่าพิจารณา เพราะช่วยให้การนำทางตอบสนองเร็วขึ้น และลดภาระทั้งฝั่งเซิร์ฟเวอร์และไคลเอนต์
ถ้าจำเป็น ก็ยังผสาน Turbo กับ Mercure เพื่อสตรีมหน้าแบบเรียลไทม์ได้ด้วย
ความแตกต่างที่ใหญ่ที่สุดระหว่างเว็บไซต์สแตติกกับเว็บไซต์ไดนามิกคือ พื้นผิวการโจมตีด้านความปลอดภัย
ในกรณีเลวร้ายที่สุด เว็บเซิร์ฟเวอร์ของเว็บไซต์สแตติกอาจถูกชักจูงให้เสิร์ฟไฟล์ผิดไฟล์ได้เท่านั้น และก็ลดความเสี่ยงได้ด้วยการอัปโหลดขึ้นเซิร์ฟเวอร์เฉพาะไฟล์ที่ควรเสิร์ฟอยู่แล้ว
ส่วนเว็บไซต์ไดนามิกอาจถูกชักจูงให้รันโค้ดได้ หรือทำให้คืนค่าข้อมูลที่ไม่ถูกต้องจากฐานข้อมูลที่เข้าถึงได้ หรือแม้แต่ทำให้ข้อมูลถูกแก้ไขได้
WordPress ถูกเจาะเกิดขึ้นตลอด แต่ Nginx ไม่ได้เป็นแบบนั้น
ในเชิงเทคนิคแล้ว ไม่มี เว็บไซต์ที่ไม่รันโค้ด ตั้งแต่เว็บเซิร์ฟเวอร์ ไดรเวอร์ระบบไฟล์ ไปจนถึงระบบปฏิบัติการ ล้วนเป็นโค้ดทั้งหมด
จริงอยู่ที่ไฟล์สแตติกช่วยลดพื้นผิวการโจมตี แต่ควรคิดให้ลึกว่าทำไมถึงเป็นแบบนั้น แล้วออกแบบระบบไดนามิกที่ชาญฉลาดซึ่งมีความปลอดภัยแบบเว็บไซต์สแตติก
สุดท้ายแล้วหัวใจสำคัญคืออินพุตและวิธีจัดการกับอินพุตนั้น ต่อให้รันโค้ดซับซ้อนแค่ไหน ถ้าไม่รับอินพุตเลยก็โจมตีไม่ได้ แน่นอนว่าถ้าไม่มีอินพุตก็จะไม่รู้ด้วยซ้ำว่าต้องแสดงหน้าไหน ดังนั้นเว็บไซต์สแตติกก็มีอินพุตเหมือนกัน จุดแบ่งสำคัญอยู่ตรงนี้
ผมเห็นด้วยว่าพื้นผิวการโจมตีของเว็บไซต์สแตติกเล็กกว่า แต่คิดว่าเหตุผลที่ใหญ่กว่าคือ nginx ผ่านการตรวจสอบมามากกว่าชุดปลั๊กอิน WordPress โดยเฉลี่ยอย่างมาก และพัฒนาด้วยความเร็วที่ช้ากว่า
ถ้าคุณสร้างเว็บเซิร์ฟเวอร์สแตติกขึ้นมาเอง เวอร์ชันแรกมีโอกาสสูงที่จะเปราะบางต่อการโจมตีมากกว่าการติดตั้ง WordPress แบบพื้นฐาน
ในทางทฤษฎี เว็บไซต์สแตติกอาจไม่ต้องอัปเดตอะไรเลยก็ได้ ตราบใดที่เป้าหมายอย่างเวอร์ชัน HTML ไม่เปลี่ยน แทบไม่มีแนวคิดเรื่องการอัปเดตเลย
locationblock ที่มีคำสั่งaliasในมุมมองของนักพัฒนา การแบ่งแยกโดยยึดตามแอ็บสแตรกชันที่เว็บมอบให้ หรือก็คือ ไฮเปอร์มีเดีย ที่ทำงานอยู่บน HTTP/S นั้นค่อนข้างชัดเจน
ความหมายเชิงอรรถศาสตร์ของแอ็บสแตรกชันนี้คือ มีคำขอที่ประกอบด้วยเฮดเดอร์และเนื้อหาส่งเข้ามาที่เส้นทางหนึ่ง แล้วมีคำตอบที่ประกอบด้วยเฮดเดอร์และเนื้อหาส่งกลับออกไป โดยรายละเอียดเครือข่ายระหว่างทางอย่าง TLS จะถูกซ่อนไว้
ในความเป็นจริง เฟรมเวิร์กสมัยใหม่ยังจัดการแม้กระทั่งเซสชันการยืนยันตัวตนและเฮดเดอร์ของคำขอให้อัตโนมัติ ทำให้ซ่อนรายละเอียดจากนักพัฒนาไปมากยิ่งขึ้น ภายในแอ็บสแตรกชันนี้ การแบ่งมาตรฐานที่ว่า “สแตติกไม่ขึ้นกับคำขอ/สถานะ ส่วนไดนามิกขึ้นกับสิ่งเหล่านั้น” ดูชัดเจนดี แต่การแบ่งนี้ก็อาศัยอรรถศาสตร์ที่แอ็บสแตรกชันมอบให้
มันคล้ายกับที่ TCP ทำงานเป็นโปรโตคอลแบบเชื่อมต่อ บนโครงสร้างชั้นล่างที่โดยพื้นฐานเป็นแบบแพ็กเก็ต คุณสามารถใช้ TCP กับแอปพลิเคชันที่ต้องการการส่งข้อมูลแบบสตรีมหรือแบบแพ็กเก็ตก็ได้
จะอ้างว่า “ในความเป็นจริงมันอยู่บน IP ดังนั้นจึงไม่มีการแบ่งแยก” ก็ได้ แต่แบบนั้นคือการมองจากชั้นแอ็บสแตรกชันที่ไม่ถูกต้อง
ทั้งนี้ก็ไม่ได้หมายความว่าใจความของบทความผิด นักพัฒนาควรตระหนักเสมอถึงความมีสถานะที่อยู่ใต้ “เว็บไซต์ไร้สถานะ” และควรทำความเข้าใจแอ็บสแตรกชันให้ลึกกว่าที่คิดว่าจำเป็นอีกหลายชั้น
เว็บไซต์ส่วนตัวเป็นการผสมกันอย่างแปลก ๆ ระหว่างสแตติกกับไดนามิก ส่วนใหญ่เป็นสแตติก แต่ส่วนบล็อกเป็น การเรนเดอร์แบบไดนามิก
เมื่อเข้าถึง URL ของบล็อก ระบบจะดึงไฟล์ Markdown จากดิสก์ แปลงเป็น HTML แล้วนำ HTML นั้นไปใส่ในเทมเพลตเพื่อประกอบส่วนที่เหลือของหน้าและ CSS เป็นต้น
ถึงอย่างนั้นมันก็ยังเร็วและมีประสิทธิภาพ สัปดาห์ก่อนตอนที่โพสต์บล็อกของฉันอันหนึ่งขึ้นอันดับ 1 บน HN เพื่อนส่งข้อความมาถามว่า “หวังว่านายตั้งค่า Cloudflare ไว้แล้วนะ” ฉันไม่ได้ตั้งค่าไว้ แต่ค่าโหลดเฉลี่ยของ VPS 2 คอร์ หน่วยความจำ 1GB ก็ไม่เคยเกิน 0.15
ประมาณว่า “ส่วนใหญ่เป็น HTML แต่พอมาถึงบรรทัดนี้ของไฟล์ ก็รันโค้ดเพื่อพาร์สไฟล์อีกแบบหนึ่ง แล้วแทรกผลลัพธ์ลงในเอาต์พุต”
ในปี 2001 นี่เป็นวิธีที่สมเหตุสมผลมากในการสร้างเว็บไซต์สแตติกที่มีส่วนอย่างคอมเมนต์ใต้แต่ละโพสต์บล็อก PHP แบบนี้มีต้นทุนต่ำพอที่โดยทั่วไปแม้แต่ ISP ก็ยังมักยอมให้เอาไปวางไว้ที่
/~userdir/และเปิดให้เข้าถึงจากอินเทอร์เน็ตสาธารณะได้ถ้าเป็นโครงสร้างที่สมเหตุสมผลและไม่ได้พึ่งฐานข้อมูลหนักเกินไป VPS ขนาดเล็กก็รับทราฟฟิกจาก Hacker News ได้สบาย
ถ้าคุณจะเปิดตัว Threads คุณอาจต้องใช้วิธีสเกลแบบที่ Facebook ทำ แต่ถ้าเป็นเว็บอ่านอย่างเดียวทั่วไป ก็ไม่มีเหตุผลอะไรเลยที่จะต้องใช้เงินมาก
พอนึกออกได้ว่าอาจเป็นเพราะต้องการใส่เนื้อหาไดนามิกลงในเทมเพลต หรือเพื่อลดเวลาและความซับซ้อนตอนบิลด์ แต่ก็อาจมีเหตุผลอื่นที่ฉันยังนึกไม่ถึงเหมือนกัน
ในมุมของคนนอกที่พอแตะ ๆ
wasmอยู่บ้าง ผมไม่ค่อยเข้าใจว่าทำไมการรันโค้ดของผู้ใช้บนเซิร์ฟเวอร์เพื่อสร้างเว็บเพจแบบ “ไดนามิก” ถึงดีกว่าไฟล์เซิร์ฟเวอร์ธรรมดาส่วนที่ไดนามิกก็ให้รันในเบราว์เซอร์ไป แล้วฝั่งเซิร์ฟเวอร์ก็แค่เสิร์ฟไฟล์อย่างเดียวไม่พอหรือ ยกเว้นก็แค่กรณีที่เบราว์เซอร์ยุค 90 ทำงานพวกนี้ได้แย่มาก
ในแง่ความเรียบง่ายและการขยายระบบ ไม่มีอะไรชนะ ไฟล์เซิร์ฟเวอร์ธรรมดาที่วางไว้หลัง CDN ได้
อีกอย่างคือมีเทคโนโลยีมากแค่ไหนที่ไม่ทำลายความสามารถพื้นฐานของเบราว์เซอร์
ยกตัวอย่าง GitHub เวลาผมไล่ดูซอร์สโค้ด ปุ่มย้อนกลับยังพังในเครื่องผมอยู่ราว ๆ 40% ของเวลา ผมใช้ Chrome บน OSX และก็ไม่รู้เหมือนกันว่ามันเป็นแบบนั้นได้ยังไง
จากประสบการณ์ของผม เว็บที่สร้าง HTML ฝั่งเซิร์ฟเวอร์ให้ความรู้สึกว่าเร็วและเสถียรกว่าเว็บที่พึ่งการเรนเดอร์ฝั่งไคลเอนต์เสมอ แม้ตอนที่ browser cache ว่างอยู่ การเปิด booru ที่มีรูปเกิน 50 รูปต่อหน้าก็ยังให้ความรู้สึกว่าเร็วและลื่นกว่าการเปิดหน้า GitHub ที่มีแต่ข้อความซึ่งแคชไว้ตามจุดต่าง ๆ อยู่แล้วและแทบไม่ได้เปลี่ยนมาหลายวัน
เช่น คุณอาจอยากเก็บเนื้อหาที่ผู้ใช้ส่งเข้าไปไว้ในฐานข้อมูล ต้องมีการยืนยันตัวตน หรือให้บริการ full-text search บนชุดข้อมูลขนาดหลาย GB ก็ได้ คุณอาจต้องทำอินเทอร์เฟซให้กับสิ่งที่เบราว์เซอร์เข้าถึงไม่ได้ หรืออาจต้องตรวจสอบข้อมูลที่ผู้ใช้ป้อน
ทั้งหมดนี้ต้องใช้โค้ดฝั่งเซิร์ฟเวอร์ที่รันอยู่ จากนั้นก็ต้องแปลงข้อมูลบนเซิร์ฟเวอร์ให้เป็นโปรโตคอลรับส่งข้อมูลที่กำหนดไว้ชัดเจน ส่งไปยังไคลเอนต์ แล้วค่อยแปลงกลับมาเป็น HTML
ฝั่งย้อนกลับก็เหมือนกัน ถ้าจะกันไคลเอนต์ดัดแปลงที่ประสงค์ร้าย คุณก็ต้องตรวจสอบข้อมูลนำเข้าทั้งฝั่งไคลเอนต์และเซิร์ฟเวอร์
หรือจะให้เซิร์ฟเวอร์สร้างเป็น HTML ไปเลยแล้วจบก็ได้ งานน้อยกว่ามาก และสำหรับแอปส่วนใหญ่ก็แทบให้ประสบการณ์เดียวกัน
ถ้ามี ค่าความลับ ที่ต้องซ่อนไว้ เช่น รหัสผ่านฐานข้อมูล, API key, กุญแจเข้ารหัส โค้ดฝั่งเซิร์ฟเวอร์ก็ต้องเป็นคนจัดการ ถ้าโค้ดทั้งหมดรันอยู่ฝั่งไคลเอนต์ ผู้โจมตีก็มีโอกาสค้นพบค่าลับเหล่านั้นได้เสมอ
การให้ API ฝั่งไคลเอนต์ที่เล็กและจำกัดกว่ามักช่วยลดพื้นที่การโจมตีได้ง่ายกว่า ถ้าปล่อยให้ไคลเอนต์ต่อฐานข้อมูลโดยตรง ก็ต้องมั่นใจว่าสิทธิ์และการตั้งค่าความปลอดภัยถูกต้องและไม่มีช่องโหว่ แต่ถ้าแอปให้แค่รายการหนังสือหรือภาพยนตร์ที่ต้องใช้ ก็จะทะลวงแนวป้องกันได้ยากกว่า
การส่งข้อมูลก้อนเดียวที่พร้อมใช้งานได้ทันทีตั้งแต่โหลดครั้งแรกก็มักทำให้เว็บรู้สึกตอบสนองได้ดีกว่า ถึงเวลาจริงจะเท่ากันกับวิธีที่ต้องดาวน์โหลดแอป แสดงตัวโหลด แล้วค่อยดึงข้อมูลมาแสดง ผู้ใช้ก็มักรู้สึกว่าวิธีแรกเร็วกว่า
โดยปกติเซิร์ฟเวอร์จะอยู่ใกล้ฐานข้อมูลและเซิร์ฟเวอร์อื่น ๆ ที่ต้องใช้ จึงอาจเร็วกว่าถ้าโหลดสิ่งที่ต้องใช้ให้ครบจากฝั่งหน้า ระบบเรียกเครือข่ายในสภาพแวดล้อมแบบนี้ก็เสถียรกว่า ถ้าผลักทุกอย่างไปให้ฝั่งผู้ใช้จัดการ ก็ต้องรับมือกับการเรียกที่ช้ากว่าและไม่นิ่งกว่า
เซิร์ฟเวอร์มักเป็นแพลตฟอร์มที่สม่ำเสมอกว่าเบราว์เซอร์ของผู้ใช้มาก แม้เบราว์เซอร์จะดีขึ้นแล้ว แต่ก็ยังมีความต่างจุกจิกอยู่เยอะ ฝั่งเซิร์ฟเวอร์สามารถระบุเครื่องมือและเวอร์ชัน runtime ที่ต้องการได้เป๊ะกว่า และอัปเดตได้แบบกำหนดผลลัพธ์ได้มากกว่า
แน่นอนว่านี่ไม่จริงเสมอไปและมีข้อยกเว้น ผมเองก็ทำงานกับแอปฟรอนต์เอนด์เป็นหลัก และก็เห็นคุณค่ามากของแอปที่ออกแบบมาดีซึ่งทำงานส่วนใหญ่หรือทั้งหมดในเบราว์เซอร์ เพียงแต่โดยมากมันจะเป็นเว็บแอปที่ค่อนข้างซับซ้อน หรือไม่ก็เป็นกรณีที่ยังไงก็ต้องเรนเดอร์ในเบราว์เซอร์อยู่พอสมควร
การสร้างเกิดขึ้นแค่ครั้งเดียวและเสร็จเร็วมาก หลังจากนั้นข้อดีมากมายของหน้าแบบสแตติกก็ยังใช้ได้เหมือนเดิมจากมุมมองของผู้ใช้
การใช้ทรัพยากรน้อยกว่าหลายลำดับขนาด และหน้าก็ตอบสนองได้ดีกว่ามาก ประสบการณ์ผู้ใช้ก็ดีกว่ามากด้วย ซึ่งตลอด 10 ปีที่ผ่านมาเราแทบไม่ได้ใส่ใจเรื่องนี้กันเลย
rsyncเท่านั้น ทุกหน้าถูกเรนเดอร์แบบไดนามิกข้อดีคือพอตั้งค่าเสร็จครั้งเดียวแล้ว ผมแทบไม่ต้องสนใจเว็บไซต์อีกเลยตามตัวอักษร แค่เขียน Markdown ที่ชอบก็พอ
มันดีมาก จนกระทั่งผู้ให้บริการเว็บโฮสติงเลิกให้ใช้ PHP
ด้วยเหตุนี้ผมเลยชอบ การ export หน้าแบบสแตติกของ NextJS มาก
สั่ง build แล้ว deploy แค่ไฟล์
.html,.js,.cssแบบสแตติกไปยัง CDN หรือสแตติกเว็บเซิร์ฟเวอร์ที่ต้องการได้เลย แต่ละหน้าและเส้นทางจะถูก pre-render ไว้ล่วงหน้าตอน build ทำให้โหลดครั้งแรกเร็วมากและเสิร์ชเอนจินก็ทำดัชนีได้วิธีที่ NextJS แบ่งโค้ด
.jsเป็น chunk และ preload ก็ช่วยให้ประสบการณ์การโหลดเร็วขึ้นด้วย ถ้าต้องการฟีเจอร์ที่หลากหลายก็เชื่อมกับ REST API ที่ต้องการแล้วทำให้ไดนามิกได้ตามสบายถ้าใช้ปลั๊กอิน MDX ก็ยังทำส่วนที่เป็นสแตติกเต็มตัวหรือเว็บแนวเนื้อหาในโปรเจ็กต์เดียวกันได้ง่ายด้วย
แต่พอมี app router ใน v13 ก็รู้สึกว่าฟีเจอร์ export แบบสแตติกไม่ได้รับการดูแลเท่าที่ควร ฟีเจอร์บางอย่างที่เคยมีใน page router อย่าง shallow routing และ static rewrites/redirects หายไปจากการ export แบบสแตติก
ถ้าใช้ static export ก็แทบไม่ต้องใช้ผลิตภัณฑ์ Vercel เชิงพาณิชย์เลย จึงกังวลว่าในระยะยาวฟีเจอร์นี้อาจถูกถอดทิ้งไปเลย
ส่วนใหญ่ไม่ต้องใช้แม้แต่ JavaScript และไม่ต้องใช้ React, JSX, middleware หรือ server-side rendering ด้วย
ยากจะนึกภาพการดูแลรักษาระยะยาวของอะไรที่มีชิ้นส่วนเคลื่อนไหวและ dependency จาก npm มากขนาดนี้ ไม่ได้แปลว่ามันไม่มีประโยชน์ แต่ก่อนจะกระโดดเข้าไปทำโปรเจ็กต์ที่มี Git checkout 1.8 GiB และโค้ด 828,128 บรรทัด แค่เพื่อทำ landing page หน้าเดียว ก็ควรเลือกทางที่เรียบง่ายไว้ก่อน
ดูตัวอย่างของ Dan Abramov ได้: https://gist.github.com/gaearon/9d6b8eddc7f5e647a054d7b33343...
ไม่ใช่เพราะโมเดลธุรกิจของ Vercel แต่เพราะสัดส่วนการใช้งานของ Next.js ทำให้กรณีใช้งานแบบนี้พบได้น้อยกว่า
ผมไม่ค่อยแน่ใจว่า “static rewrites” หมายถึงอะไร มันไม่ใช่สิ่งที่ middleware จัดการหรือ?
ช่วงหนึ่งในยุค 90 ก่อนจะได้ยินคำว่า “เครื่องสร้างเว็บไซต์แบบสแตติก” ฉันสร้างเว็บไซต์ของตัวเองด้วย m4
หลังจากนั้นก็ย้ายไปใช้ PHP, Python และตอนนี้ใช้ Jekyll เลยวนกลับมาสู่ความเป็นสแตติกอีกครั้ง
ถ้าทำได้ วิธีแบบสแตติกดีกว่ามาก ฉันสามารถแก้ทุกอย่างตามตารางเวลาของตัวเองได้ ยกเว้นแค่ใบรับรอง SSL
ถ้ามีอะไรพังเพราะการอัปเกรด PHP ก็ต้องรีบแก้ทันที ต่างจากกรณีที่เว็บล่มอยู่จนกว่าจะแก้เสร็จ
สำหรับเว็บไซต์สแตติก ต่อให้ตัว generator พังก็แค่คงสภาพเดิมแบบสแตติกไว้ ถ้าไม่จำเป็นต้องลงบทความใหม่ก็ไม่มีปัญหา
ต่อให้เซิร์ฟเวอร์พัง ก็แค่ขอให้เพื่อนช่วยโฮสต์ไฟล์ไม่กี่ไฟล์ให้หน่อยได้เลย ไม่ต้องถามว่า “นายรันบน PHP เวอร์ชัน X พร้อมคอนฟิก Y ใช่ไหม? มี postgres ด้วยใช่ไหม?”
เพื่อนบางคนอาจจะพูดว่า “ฉันไม่อยากลง PHP บนคอมตัวเอง” ก็ได้
ถ้ามองเรื่องความซับซ้อน มันให้ความรู้สึกว่าเหนือกว่า
sed "s/VERSION/1.2.3/g"ขึ้นมาแค่ขั้นเดียว ถ้าจัดการทุกอย่างด้วยคำสั่งเชลล์ภายนอกได้ ก็ไม่จำเป็นต้องติดตั้งอะไรอย่าง Pythonหลายปีมานี้ฉันลองสำรวจรูปแบบสถาปัตยกรรมที่ให้ข้อดีของทั้งแบบสแตติกและไดนามิก
คือยังรันโค้ดฝั่งเซิร์ฟเวอร์แบบไดนามิกได้ แต่มีต้นทุนการสเกลต่ำมาก และถ้ามีอะไรพังก็ฟื้นตัวได้เอง
ผมเรียกมันว่าแพตเทิร์น Baked Data: https://simonwillison.net/2021/Jul/28/baked-data/
แนวคิดหลักคือแจกจ่ายสำเนาแบบอ่านอย่างเดียวของข้อมูลทั้งเว็บไซต์เป็น asset ที่ผูกมากับแอปพลิเคชัน
เหมือนเว็บไซต์สแตติกเต็มรูปแบบตรงที่ต้อง deploy ทั้งเว็บไซต์ใหม่ทุกครั้งที่มีการเปลี่ยนแปลง จึงไม่เหมาะกับเว็บที่อัปเดตตลอดเวลา
ข้อดีคือสามารถ deploy ไปยังโฮสติ้งไดนามิกแบบ scale-to-zero ราคาถูกอย่าง Vercel ได้ เปิดสำเนาแอปหลายชุดเพื่อรองรับทราฟฟิกเท่าไรก็ได้ และถ้าแอปตาย โฮสต์ก็รีสตาร์ตให้อัตโนมัติได้
ฉันเคยเห็นเว็บไซต์สแตติกที่มีระบบค้นหาฝั่งเซิร์ฟเวอร์หรือระบบคอมเมนต์ โดยส่งแต่ละโพสต์หรือคอมเมนต์เป็นไฟล์แบนแยกกัน แล้วจากนั้นก็สร้างหน้าเว็บสแตติกใหม่อัตโนมัติ
เลยเดาว่าความต่างคือเก็บไว้ใน sqlite แทนไฟล์ Markdown แล้ว build จากตรงนั้นหรือเปล่า เมื่อเทียบกับเว็บไซต์สแตติกทั่วไปที่มีฟังก์ชันแบ็กเอนด์/ฝั่งเซิร์ฟเวอร์ ก็ดูเหมือนมีความต่างที่เด่นชัดและมีนัยสำคัญอยู่แค่นั้น
ในอดีต การใส่ binary resource ที่เข้ารหัสแล้ว เช่น ไฟล์หรือรูปภาพ เข้าไปในไฟล์ไบนารีที่คอมไพล์เสร็จ ไม่ใช่เรื่องแปลก เพียงแต่ไม่ค่อยใส่กันเยอะเพราะขนาดไฟล์จะใหญ่ขึ้น
ตัวอย่างใน C หรือ C++: https://github.com/graphitemaster/incbin
สิ่งที่น่าสนใจคือเราออกแบบโปรแกรมให้ข้อมูลในไฟล์ executable ไม่เปลี่ยนแปลง โค้ดที่คอมไพล์แล้วจะไปรันบนเครื่อง ซึ่งในแง่ความปลอดภัยก็ดูสมเหตุสมผล
แต่พอมองคอนเทนเนอร์ เช่น docker คอนเทนเนอร์ที่กำลังรันอยู่ก็คล้ายไฟล์ executable ที่ถูกแพ็กมาแล้ว แต่มีระบบไฟล์อยู่ด้วย
ถ้าใส่ข้อมูลเข้าไปในคอนเทนเนอร์ ก็เป็นแนวคิดคล้าย resource ที่ฝังอยู่ในไฟล์ executable ต่างกันตรงที่ข้อมูลนั้นเปลี่ยนได้
เพียงแต่ว่าต่อให้ข้อมูลในคอนเทนเนอร์เปลี่ยนตอนรันไทม์ ถ้าไม่ต่อ persistent storage มันก็จะไม่คงอยู่
ช่วงหลังมานี้เลยสงสัยว่าทำไมเราไม่สร้างอะไรอย่างไฟล์เดี่ยวที่มี “ตัว executable และพื้นที่ข้อมูลชั่วคราวอยู่ข้างใน executable” โปรแกรมกับข้อมูลอย่างฐานข้อมูลก็น่าจะรวมเป็นไฟล์เดียวกันได้
มันเป็นความคิดที่เกี่ยวข้องกับ “Baked Data” อยู่เล็กน้อย การฝัง resource ในไฟล์ executable ก็คือการเอาข้อมูลที่เข้ารหัสแล้วใส่เข้าไปใน executable นั่นเอง
ในภาษาแบบสคริปต์ เราสามารถสร้างไฟล์สคริปต์ที่เก็บข้อมูลซึ่งเข้ารหัสด้วย base64 ไว้ในตัวแปรได้โดยตรง
สองวิธีหลังนี้เหมาะกับข้อมูลสแตติกขนาดค่อนข้างเล็กเท่านั้น แต่ถ้ามีเทคโนโลยีที่ช่วยยกข้อจำกัดแบบนี้ของไฟล์ executable ขึ้นได้ก็น่าจะน่าสนใจ
หน้าโปรเจกต์ของผมก็โฮสต์แบบนี้เช่นกัน: https://usmanity.com/projects
เพราะไม่อยากแก้ไฟล์ HTML ตรงๆ ทุกครั้งที่เพิ่มโปรเจกต์ใหม่ในรายการหรือเปลี่ยนรายละเอียดของรายการเดิม ผมเลยใช้ Notion แล้วค่อย bake ข้อมูลเข้าไปก่อน commit ขึ้น GitHub
พอเปิดใช้ มันจะ bake ทุกหน้าของเว็บไซต์ออกมาเป็น HTML ในไดเรกทอรี แล้วแก้
.htaccessให้ส่งทราฟฟิกทั้งหมดไปทางนั้น ถ้ามีการอัปเดตเนื้อหา ก็ bake ใหม่ทั้งหมดhttps://www.drupal.org/project/boost
สำหรับเว็บไซต์แบบสแตติก สิ่งสำคัญที่ยังขาดไปมากคือ จะโฮสต์ CMS สำหรับแก้ไขไว้ที่ไหน
ถ้าผมเข้าใจผิดก็ช่วยแก้ให้ที แต่ Decap CMS (เดิมคือ Netlify CMS) รันในเบราว์เซอร์ และสามารถอ่าน/แก้ไขผ่าน GitHub แล้วสั่ง trigger การ rebuild และ deploy ได้
แต่เพราะ CORS เบราว์เซอร์จึงคุยกับ GitHub API โดยตรงไม่ได้ ทำให้ยังคงต้องมีเซิร์ฟเวอร์เล็ก ๆ หรือพร็อกซีอยู่ดี
Netlify โฮสต์ GitHub backend ที่ทำหน้าที่พร็อกซีคำขอให้ได้ แต่แบบนั้นก็เท่ากับต้องผูกกับ Netlify และการเปลี่ยนแปลงนโยบายราคา
GitLab กับ BitBucket ก็น่าจะมีปัญหาเดียวกัน: https://github.com/isomorphic-git/isomorphic-git#cors-suppor...
มีวิธีง่าย ๆ ที่แก้ปัญหานี้ได้ด้วยการตั้งค่าน้อยที่สุดไหม? จะใช้ส่วนขยายเบราว์เซอร์เพื่อผ่อนคลาย CORS แบบเลือกได้ก็คงพอทำได้ แต่ไม่ใช่วิธีที่เหมาะนัก
ถ้ามี CMS ที่พ่วงกับตัวสร้างเว็บไซต์สแตติกแบบใช้ Git รองรับการแก้ไข Markdown และพรีวิวแบบเรียลไทม์ รันในเบราว์เซอร์ และมีข้อจำกัดด้านโฮสต์/เซิร์ฟเวอร์น้อย ก็น่าจะเหมาะกับเว็บไซต์เล็ก ๆ และบล็อกจำนวนมาก
ตัวสร้างไซต์สแตติกก็แค่อ่านข้อมูลนั้นผ่าน JSON feed อะไรทำนองนี้แล้วสร้างหน้าเว็บออกมา เช่น ในเรคอร์ดของสินค้าแต่ละชิ้นอาจมีคำอธิบายเนื้อหาหลักในรูปแบบ HTML รวมอยู่ด้วย
แบบนั้นคนอื่นก็อัปเดตข้อมูลสินค้าได้ ขณะที่เว็บไซต์ก็ยังคงเป็นสแตติกอยู่ดี ตอนแรกคิดว่า Airtable น่าจะเหมาะ แต่กลับรองรับฟิลด์ HTML ได้ไม่ดีเท่าไร
คุณสร้างเว็บไซต์ในแบบที่ต้องการ แล้วเชื่อม Surreal ผ่าน FTP จากนั้นก็ให้ผู้ใช้หรือลูกค้าแก้ไขได้เฉพาะส่วนที่อนุญาต
ราคา 12 ดอลลาร์ต่อเดือนถือว่าถูกมากเมื่อเทียบกับการไม่ต้องกังวลเรื่องพวกนี้อีก และยังให้ผู้ใช้ที่ไม่ใช่สายเทคนิคใช้งานตัวแก้ไข WYSIWYG แบบเต็มรูปแบบได้
[1] https://www.surrealcms.com
ตอนนี้ส่วนขยายนี้ทำงานได้บน VS Code ที่ติดตั้งแบบโลคัลบนโน้ตบุ๊ก แต่ไม่ทำงานบน GitHub Codespaces
ถ้าทำให้มันใช้งานได้ภายในโควตา GitHub Codespaces ฟรี พร้อมจำกัดเวลาใช้งานได้พอเหมาะ ก็น่าจะเป็นผู้ชนะเลย เพราะจะได้ระบบที่ออนไลน์ทั้งหมด มีการจัดการเวอร์ชัน และไม่ต้องติดตั้งสภาพแวดล้อมพัฒนาบนเครื่องตัวเอง ขณะที่เว็บไซต์สแตติกก็เสิร์ฟจากที่อย่าง S3 ได้ และยังคงได้ประสบการณ์แบบ CMS เต็มรูปแบบ
จุดสำคัญมากของเว็บไซต์สแตติกคือมัน ปล่อยขึ้นไปแล้วลืมได้ง่ายกว่ามาก
ถ้าเอาไปวางไว้บนอะไรอย่างเว็บไซต์ในบักเก็ต S3 ก็แทบไม่ต้องกังวลอะไร
แต่ถ้าทำเว็บไซต์แบบ “ปล่อยไว้แล้วลืม” ด้วย PHP หรือแย่กว่านั้นคือ WordPress ที่โฮสต์เอง พอไม่เข้าไปดูสักสองสามเดือน มันอาจเต็มไปด้วยโฆษณาหนังโป๊ภาษารัสเซียได้
ผมดูแลเว็บไซต์สแตติกอยู่หลายเว็บ และมันดีมากที่รู้ว่ามันจะออนไลน์อยู่ตลอดและไม่ต้องซ่อมอะไรเลย ในทางกลับกัน เว็บไซต์แบบไดนามิกต้องมีการแจ้งเตือนให้เช็กว่าเว็บล่มหรือไม่