Astro Framework: Xây Dựng Website Siêu Nhanh với Content-First
Khám phá Astro - framework tập trung vào performance và developer experience cho website hiện đại
Astro Framework: Website Siêu Nhanh
Trong thế giới web development hiện đại với vô số frameworks, Astro nổi lên như một lựa chọn thú vị với triết lý “ship less JavaScript”. Hãy cùng tìm hiểu tại sao!
Astro là gì?
Astro là một web framework hiện đại tập trung vào:
- ⚡ Performance - Tốc độ load cực nhanh
- 🎨 Flexibility - Hỗ trợ nhiều UI frameworks
- 🚀 Developer Experience - DX tuyệt vời
Đặc điểm nổi bật
// Astro component with "Islands Architecture"
---
import ReactCounter from './ReactCounter.jsx';
import VueCalendar from './VueCalendar.vue';
---
<div>
<h1>Welcome to Astro</h1>
<!-- React component - chỉ load JS khi cần -->
<ReactCounter client:visible />
<!-- Vue component - hydrate khi idle -->
<VueCalendar client:idle />
</div>
Tại sao chọn Astro?
1. Zero JavaScript by Default
Không như React hay Vue, Astro mặc định không ship JavaScript xuống client:
- Website tĩnh siêu nhanh
- SEO tuyệt vời
- Core Web Vitals hoàn hảo
2. Islands Architecture
Astro sử dụng kiến trúc “Islands”:
- Trang web là “biển” HTML tĩnh
- Components tương tác là các “đảo” JavaScript
- Mỗi island độc lập, hydrate khi cần
3. Bring Your Own Framework
Sử dụng framework bạn thích:
- React ⚛️
- Vue 💚
- Svelte 🧡
- Solid 💙
- Preact, Lit, và nhiều hơn!
Getting Started
Khởi tạo project
# Tạo project mới
npm create astro@latest
# Di chuyển vào folder
cd my-astro-site
# Cài đặt dependencies
npm install
# Start dev server
npm run dev
Cấu trúc project
my-astro-site/
├── src/
│ ├── components/ # Astro components
│ ├── layouts/ # Layout templates
│ ├── pages/ # Routes (file-based routing)
│ └── styles/ # CSS files
├── public/ # Static assets
└── astro.config.mjs # Configuration
Astro Components
Component cơ bản
---
// Component script (runs at build time)
const greeting = "Hello";
const name = "World";
// Fetch data at build time
const posts = await fetch('https://api.example.com/posts')
.then(res => res.json());
---
<!-- Template (HTML + expressions) -->
<div class="greeting">
<h1>{greeting} {name}!</h1>
<ul>
{posts.map(post => (
<li>
<a href={`/blog/${post.slug}`}>
{post.title}
</a>
</li>
))}
</ul>
</div>
<style>
/* Scoped CSS - tự động scope! */
.greeting {
padding: 2rem;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 8px;
}
</style>
Props và TypeScript
---
interface Props {
title: string;
description?: string;
publishDate: Date;
}
const { title, description, publishDate } = Astro.props;
---
<article>
<h1>{title}</h1>
{description && <p class="description">{description}</p>}
<time>{publishDate.toLocaleDateString()}</time>
</article>
Content Collections
Quản lý content dễ dàng với Collections:
// src/content/config.ts
import { defineCollection, z } from 'astro:content';
const blog = defineCollection({
schema: z.object({
title: z.string(),
description: z.string(),
pubDate: z.date(),
tags: z.array(z.string()),
image: z.string().optional(),
}),
});
export const collections = { blog };
---
// src/pages/blog/[...slug].astro
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
const posts = await getCollection('blog');
return posts.map(post => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<article>
<h1>{post.data.title}</h1>
<Content />
</article>
Client Directives
Kiểm soát khi nào JavaScript được load:
---
import InteractiveComponent from './Interactive.jsx';
---
<!-- Load ngay lập tức -->
<InteractiveComponent client:load />
<!-- Load khi component visible -->
<InteractiveComponent client:visible />
<!-- Load khi browser idle -->
<InteractiveComponent client:idle />
<!-- Load chỉ trên mobile/desktop -->
<InteractiveComponent client:media="(max-width: 768px)" />
<!-- Không load JS, chỉ render HTML -->
<InteractiveComponent />
Integrations
Mở rộng chức năng với integrations:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import tailwind from '@astrojs/tailwind';
import react from '@astrojs/react';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
integrations: [
tailwind(),
react(),
sitemap(),
],
// Server-side rendering
output: 'server',
});
Popular Integrations
- Tailwind CSS: Utility-first CSS
- MDX: Markdown + JSX
- Partytown: Web workers cho 3rd-party scripts
- Cloudflare: Deploy lên edge
- Vercel/Netlify: Static hosting
Performance Optimization
Image Optimization
---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.jpg';
---
<!-- Tự động optimize -->
<Image
src={heroImage}
alt="Hero"
width={1200}
height={600}
quality={80}
format="webp"
/>
Font Optimization
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="preload"
href="/fonts/custom-font.woff2"
as="font"
type="font/woff2"
crossorigin>
Deploy
Static Site
# Build site
npm run build
# Preview locally
npm run preview
# Deploy to Netlify/Vercel
# Just connect your Git repo!
SSR (Server-Side Rendering)
// astro.config.mjs
export default defineConfig({
output: 'server',
adapter: cloudflare(),
});
So sánh với frameworks khác
Astro vs Next.js
- Astro: Tốt cho content sites, zero JS mặc định
- Next.js: Tốt cho web apps, React ecosystem
Astro vs Gatsby
- Astro: Nhanh hơn, DX tốt hơn, linh hoạt hơn
- Gatsby: Plugin ecosystem lớn, GraphQL built-in
Astro vs SvelteKit
- Astro: Multi-framework, tối ưu performance
- SvelteKit: Full-stack framework, Svelte only
Use Cases Lý Tưởng
Astro hoàn hảo cho:
- 📝 Blogs và documentation sites
- 🎨 Portfolio websites
- 📰 Marketing và landing pages
- 🏢 Company websites
- 📚 Content-heavy sites
Không phù hợp cho:
- ❌ Highly interactive SPAs
- ❌ Real-time applications
- ❌ Complex web apps với nhiều client state
Tips và Best Practices
1. Tận dụng Static Generation
---
// Fetch data at build time
const data = await fetch('https://api.example.com/data');
---
2. Lazy load images
<img loading="lazy" src="image.jpg" alt="Description">
3. Minimize client JavaScript
<!-- Chỉ thêm interactivity khi thực sự cần -->
<Component client:visible />
4. Use View Transitions API
---
import { ViewTransitions } from 'astro:transitions';
---
<head>
<ViewTransitions />
</head>
Kết luận
Astro là một framework mạnh mẽ cho những ai muốn xây dựng website với:
- ⚡ Performance tuyệt vời
- 🎯 Content-focused
- 🛠️ Developer experience tốt
- 🎨 Linh hoạt trong lựa chọn công nghệ
Nếu bạn đang build blog, portfolio, hay content site, Astro chắc chắn đáng để thử!
Resources: