ทำไมต้อง Astro และ Islands
ปัญหา: ส่งทั้ง framework ไปเพื่อ render ตัวหนังสือ
หัวข้อที่มีชื่อว่า “ปัญหา: ส่งทั้ง framework ไปเพื่อ render ตัวหนังสือ”เว็บส่วนใหญ่คือ content: blog, docs, marketing site, รายการสินค้า e-commerce การสร้างของพวกนี้ด้วย SPA ที่ render ฝั่ง client แปลว่า browser ต้องโหลด JavaScript bundle ก้อนใหญ่ boot framework ขึ้นมา แล้ว re-render — บน client — HTML ที่ทีแรกก็ส่งเป็น HTML ธรรมดาได้อยู่แล้ว
ต้นทุนตรงนี้ไม่ใช่เรื่องเล็ก: first paint ช้าลง, interactivity มาช้า (เข้าสู่ “uncanny valley” ที่หน้าดูเหมือนพร้อมแต่กดอะไรไม่ได้) และเสีย CPU ไปเยอะกับการ hydrate ส่วนที่ไม่เคย interactive เลย — footer, เนื้อบทความ, nav bar
Insight ที่ Astro สร้างขึ้นมา: สำหรับ content site แล้ว HTML คือตัวสินค้า JavaScript ควรเป็นข้อยกเว้น ไม่ใช่ฐานราก
islands architecture
หัวข้อที่มีชื่อว่า “islands architecture”Astro render ทั้งหน้าเป็น static HTML แล้วมองแต่ละ component ที่ interactive เป็น island — ชิ้นเล็ก ๆ ที่ hydrate แยกกันในทะเลของ static HTML
flowchart TB page["Page: static HTML (ไม่มี JS)"] page --> nav["nav — static"] page --> article["เนื้อบทความ — static"] page --> search["SearchBox — island (hydrated)"] page --> cart["CartWidget — island (hydrated)"] page --> footer["footer — static"]
สองคุณสมบัติที่นิยาม island:
- แยกเป็นอิสระ แต่ละ island hydrate ด้วยตัวเอง มี JavaScript ของตัวเอง เป็นอิสระจากตัวอื่น carousel ที่โหลดช้าไม่ block search box
- Opt-in ไม่มีอะไร interactive จนกว่าคุณจะ ทำเครื่องหมาย ไว้เอง (ด้วย client directive — มีบทเรียนทั้งบททีหลัง) ค่า default คือ static HTML ที่ไม่มี JavaScript เลย
เทียบกับ SPA ที่ ทั้งหน้า เป็น JavaScript application ก้อนเดียวซึ่งต้อง boot ให้เสร็จก่อนถึงจะทำอะไรได้ ส่วน islands ส่ง JavaScript เฉพาะ component ที่ต้องใช้ และส่งแค่เท่าที่ต้องใช้
Zero JS by default
หัวข้อที่มีชื่อว่า “Zero JS by default”นี่คือพาดหัว: Astro component โดย default ผลิต HTML กับ CSS และไม่มี JavaScript เขียน component ที่มีปุ่มและ onClick — เว้นแต่คุณจะเปลี่ยน component นั้นเป็น island — ปุ่มจะ render แต่ handler ไม่ถูกส่งไป นั่นไม่ใช่ข้อจำกัด แต่เป็นประเด็นสำคัญ: คุณถูกบังคับให้ตั้งใจว่าอะไรจะรันบน client
---// component นี้รันบน server เพื่อผลิต HTML// JavaScript พวกนี้ไม่ถูกส่งไป browser เลยconst posts = await getPosts();---<ul> {posts.map((post) => <li>{post.title}</li>)}</ul><!-- ส่ง: HTML <ul> ส่ง: ไม่มี JavaScript -->ผลลัพธ์คือหน้าเว็บที่เร็วตั้งแต่โครงสร้าง: browser ได้ HTML ที่ paint ได้ทันที และโหลด JavaScript เฉพาะ island ที่คุณเลือกเปิดเองอย่างชัดเจน
Astro เหมาะ (และไม่เหมาะ) ตอนไหน
หัวข้อที่มีชื่อว่า “Astro เหมาะ (และไม่เหมาะ) ตอนไหน”Astro โดดเด่นกับ content-driven site: blog, documentation, marketing, portfolio, e-commerce, อะไรก็ตามที่ส่วนใหญ่ของหน้าเป็น content และ interactivity อยู่เฉพาะจุด
Astro เหมาะน้อยกว่ากับ UI ที่เหมือนแอปและ interactive สูง — editor สไตล์ figma, trading dashboard, เครื่องมือ collaborate แบบ realtime — ที่เกือบทุกอย่างมี state และ interactive ตรงนั้น SPA framework เต็มตัว (หรือ Astro ที่มี island ใหญ่มาก ซึ่งขัดกับจุดประสงค์) จะเข้าท่ากว่า และ Astro ยังให้คุณฝัง component ของ framework พวกนั้นเป็น island ได้เมื่อจำเป็น