มารีด JavaScript ด้วย Astro กัน
Astro คืออะไร?
ในปี 2023 ได้มีโอกาสไปร่วมงาน conference ชื่อ CityJS ที่สิงคโปร์ ภายในงานมีหัวข้อหัวข้อหนึ่งชื่อ Shipless JavaScript with Astro เป็นหัวข้อหนึ่งที่ผมมีความสนใจ และในบทความนี้เลยอยากจะมาแชร์สิ่งที่ได้จาก conferenceให้ได้อ่านกัน
Astro คือ web framwork อันหนึ่ง ที่ใช้ในการ ที่ใช้ในการสร้างเว็บไซต์หรือแอพพลิเคชั่น เช่นเดียวกับ web framwork อื่นๆ อย่าง React , Vue หรือ Angular ที่มีความสามารถคล้ายๆกัน
ทำไมต้อง Astro?
ทำไมถึงต้อง เลือกใช้ Astro กันล่ะ ในเมื่อมี web framework ที่เป็นที่นิยมหรือมีชื่อเสียงมากกว่าให้เลือกใช้ บางคนอาจจะเพิ่งเคยได้ยินคำว่า Astro ด้วยซ้ำไป
รีด JavaScript
สิ่งที่ Astro เน้นหนักเลยก็คือการลดใช้ JavaScript ที่ใช้ในการ render ในฝั่ง client ตรงจุดนี้ทำให้ Astro สามารถ render web application ได้อย่างรวดเร็ว เพราะ มีการดาวน์โหลด JavaScript น้อยกว่า และใช้ JavaScript ในการช่วย render ในฝั่ง client น้อยหรือแทบไม่ใช้เลย ซึ่งถ้าลองเอามาเปรียบเทียบกับ framework อื่นๆ เช่นตัวอย่างลองเทียบกับ Nuxt กับ Astro ใช้ implement Hacker News จะเห็นว่า Astro load content น้อยกว่ามาก
Performance
นอกจากในแง่ของลดการใช้ resource แล้ว เรื่อง performance ก็เป็นอีกจุดหนี่งที่ Astro ให้ความสำคัญ ถ้าลองเทียบ Branchmark ของตัววัดที่นิยม อย่าง Core Web Vitals และ Lighthouse ของแต่ละ framework จะเห็นว่า astro มีคะแนนที่สูงกว่า framework อื่นๆ อย่างเห็นได้ชัด ตรงนี้ถ้าใครสนใจว่า data มาจากไหนสามารถ อ่านต่อได้ตาม source ข้างล่างได้เลย
source: https://astro.build/blog/2023-web-framework-performance-report/
Islands components
อีกจุดเด่นหนึ่งที่ Astro แตกต่างจาก web framework อื่นๆ คือสามารถเขียน UI component โดยใช้ภาษาที่มีความนิยม เช่น React, Vue, Rreact, Svelte, SolidJS ซึ่งเราสามารถเขียนในลักษณะ “app” ที่ render อยู่บน HTML อีกทีนึง เรียกว่า Islands
โดยที่ การทำ component ตรงนี้ เราสามารถกำหนดได้ด้วยว่า เราต้องการให้ component render ที่ server หรือที่ client แม้แต่ render ในตอน ที่ component ปรากฏครั้งแรกก็ได้
<MyReactComponent /> // Server side render
<MyReactComponent client:load/> // Client side render
<MyReactComponent client:visible/> // render once enter the viewport
จะเขียน Astro เริ่มยังไง
การติดตั้ง
อย่างแรกเลยก็คีอ generate project Astore ขึ้นมาก่อนด้วยคำสั่ง
npm create astro@latest
# หรือ
yarn create astro
# หรือ
pnpm create astro@latest
ทำตาม instruction เราก็จะได้ project Astro ออกมา
Project structure
มาทำความรู้จักกับ project structure ของ Astro ก่อน โดย source code ของเราส่วนใหญ่จะอยู่ใน `src` folder ทั้งหมด ได้แก่
— src/components ที่เก็บ component ทั้งหมด รวมไปถึง component จากภาษาอื่นๆ
— src/layouts ที่เก็บ component ที่ ต้องการ share ไปหลายๆ หน้า เช่น header, footer เป็นต้น
— src/pages ที่เก็บ หน้าเว็บของเราโดยจะมีความพิเศษตรงที่ ชื่อ folder / file จะใช้เป็น page route ในหน้าเว็บของเรา
— public ที่เก็บ file รูปภาพ หรือ file media อื่นที่ใช้ใน project
ตรงนี้จะมีรายละเอียดอยู่พอสมควร สามารถดูที่ Project struture เพิ่มเติมได้
File Astro
ต่อไปคือ astro file จะมีหน้าตาดังนี้
---
// JavaScript
import Layout from '../layouts/Layout.astro';
import Card from '../components/Card.astro';
const title = 'Astro'
const fetchData = await fetch('/api').then(r => r.json());
---
<! - HTML →
<Layout title="Welcome to {title}">
<main>
<ul>
{fetchData.map((data) => <li>{data.name}</li>)}
</ul>
</main>
</Layout>
Astro จะแบ่ง code เป็น 2 ส่วน โดยใช้ code fence ( — -) ในการแบ่ง
- ส่วนแรก คือ JavaScript ที่ จะ run บน server เท่านั้น
- ส่วนที่สอง คือ HTML ที่เราสามารถ เข้าถึง JavaScript ในส่วนแรกได้ โดยใช้ วงเล็บปีกกา ( {}
) ในการแบ่ง scope
โดย JavaScript ของ Astro file นะ run run ทุกครั้งที่มี request เข้ามา ถ้าหากต้องการให้ page render เป็น static page ก็สามารถทำได้โดยการ เพิ่ม
// add this for static page
export const prerender = true;
---
<html>
<!-- Static, pre-rendered page here… -->
</html>
Island Components
Astro จะ focus กับการ render static html แต่ว่าถ้าหากเราต้องการ dynamic component ที่ทำงาน บน client เราก็สามารถ เลือกใช้ js component ที่เราถนัดเข้ามาช่วยให้เรา ในแบบที่เราต้องการได้ เช่นตัวอย่าง React component
// file: /components/Counter.jsx
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
const onClick = function () {
setCount((count) => count + 1);
};
return (
<div className="text-center m-8">
<p>You clicked {count} times</p>
<button className="p-3" onClick={onClick}>
Click me
</button>
</div>
);
}
เราสามารถ เรียกใข้ component ได้ดังนี้
---
import Counter from "../components/Counter";
---
<Counter />
สุดท้ายนี้
ขอสรุปนะกัน สำหรับ Astro ก็เป็น web framework ที่มีความสามารถในการสร้างเว็บไซต์หรือแอพพลิเคชั่น โดยมีจุดเด่นในการลดการใช้ JavaScript ที่ใช้ในการ render ในฝั่ง client ทำให้ Astro ไว และ performance ก็ดีด้วย นอกจากนี้ Astro ยังมีความสามารถในการเขียน UI component โดยใช้ภาษาที่มีความนิยมอื่นๆอีกด้วย ใครว่างๆ ก็อย่าลีมเอาไปลองเล่นกันนะครับ