Islands กับ Client Interactivity
จาก static HTML สู่ interactivity เท่าที่จำเป็น
หัวข้อที่มีชื่อว่า “จาก static HTML สู่ interactivity เท่าที่จำเป็น”โมดูล Foundations วางหลักไว้แล้วว่า Astro ส่ง JavaScript เป็นศูนย์โดย default ซึ่งดีมากสำหรับ content แต่เว็บจริงก็ยังต้องมี search box, cart, ปุ่ม toggle theme, ปุ่ม like อยู่ดี โมดูลนี้คือการเพิ่ม interactivity เท่านั้น — และไม่มากไปกว่านั้น
หน่วยของ interactivity ใน Astro คือ island โดย island คือ framework component (React, Vue, Svelte, Solid, Preact) ที่เรา ตั้งใจ hydrate บน client ด้วย client directive ส่วนทุกอย่างรอบ ๆ island ยังเป็น static HTML เราไม่ได้เปลี่ยนทั้งหน้าให้กลายเป็น app แต่เลือก component แค่ตัวเดียวให้กลายเป็น interactive
flowchart TB page["Page: static HTML, no JS"] page --> header["header — static"] page --> search["SearchBox — island (client:load)"] page --> article["article — static"] page --> cart["Cart — island (client:visible)"] page --> footer["footer — static"]
โมดูลนี้ครอบคลุมอะไรบ้าง
หัวข้อที่มีชื่อว่า “โมดูลนี้ครอบคลุมอะไรบ้าง”| บทเรียน | สิ่งที่จะได้เรียนรู้ |
|---|---|
| Client directives | client directive ทั้งห้าตัว (client:*) และแต่ละตัว hydrate เมื่อไหร่ |
| Framework integrations | ใช้ component ของ React/Vue/Svelte/Solid/Preact เป็น island |
| Sharing state | island แยกตัวจากกัน — จะแชร์ข้อมูลข้าม island ด้วย nanostores และ slot ได้อย่างไร |
| Server islands | server:defer — defer component ที่ช้าหรือ personalize โดยไม่ทำให้หน้าช้า |
มุมมองหลักที่ต้องถือไว้ตลอดโมดูล
หัวข้อที่มีชื่อว่า “มุมมองหลักที่ต้องถือไว้ตลอดโมดูล”มีสองคำถามที่ตัดสินทุกอย่างในโมดูลนี้:
- component นี้ต้อง interactive จริงไหม? ถ้าไม่ ก็ปล่อยให้เป็น
.astrocomponent ธรรมดาที่ไม่ส่ง JS เลย — ที่เป็นส่วนใหญ่ของหน้า - ถ้าต้อง แล้ว เมื่อไหร่ ถึงต้องกลายเป็น interactive? ทันทีเลย? ตอน scroll เข้ามาในจอ? ตอนหน้าจอขนาดหนึ่ง? คำว่า “เมื่อไหร่” นี่แหละคือสิ่งที่ client directive บอก — และเป็นความต่างระหว่างหน้าที่เร็วกับหน้าที่ช้า
ถ้าถามสองคำถามนี้ไปเรื่อย ๆ island จะเลิกเป็นกอง directive ที่งง ๆ และกลายเป็น budget แทน: ทุก island คือ JavaScript ที่เราเลือกจะส่งเอง อย่างตั้งใจ