Migrasi dari Next.js ke Astro
Pengalaman migrasi blog dari Next.js 15 ke Astro dengan analisis performa, tantangan teknis, dan panduan praktis untuk developer yang ingin melakukan hal serupa.
Mengapa Migrasi dari Next.js ke Astro?
Setelah berbulan-bulan menggunakan Next.js 15 untuk blog pribadi, saya mulai merasakan beberapa “friction” yang membuat saya berpikir ulang. Bukan karena Next.js buruk—justru sebaliknya, Next.js adalah framework yang luar biasa untuk aplikasi web yang kompleks. Tapi untuk blog sederhana seperti ini, rasanya kaya pake Ferrari buat pergi ke warung sebelah.
Masalah yang Saya Hadapi dengan Next.js
1. Build Time yang Lambat Setiap kali saya ingin publish artikel baru, proses build cukup lambat jika nantinya post sudah banyak.
2. Bundle Size yang Besar Meskipun hanya menampilkan konten statis, JavaScript bundle yang dihasilkan cukup besar karena React runtime dan Next.js overhead.
3. Kompleksitas yang Tidak Perlu Fitur-fitur canggih Next.js seperti API routes, middleware, dan server components tidak saya gunakan sama sekali.
Kenapa Memilih Astro?
Astro menawarkan pendekatan yang berbeda dengan filosofi “Islands Architecture” dan “Ship Less JavaScript”. Inilah yang membuat saya tertarik:
Keunggulan Astro
1. Zero JavaScript by Default Astro hanya mengirim HTML dan CSS ke browser. JavaScript hanya dimuat ketika benar-benar diperlukan.
2. Multi-Framework Support Bisa menggunakan React, Vue, Svelte, atau vanilla JavaScript dalam satu project.
3. Build Speed yang Luar Biasa Build time yang jauh lebih cepat dibanding Next.js untuk static content.
4. SEO-Friendly Static HTML yang dihasilkan sangat SEO-friendly tanpa perlu konfigurasi tambahan.
Proses Migrasi: Step by Step
1. Setup Project Astro
npm create astro@latest astro-portfolio
cd astro-portfolio
npm install2. Migrasi Komponen React
Untuk komponen yang memerlukan interaktivitas, saya menggunakan React dengan directive client:load:
---
// src/components/ThemeToggle.astro
import ThemeToggleReact from './ThemeToggleReact.tsx';
---
<ThemeToggleReact client:load />3. Setup Routing dan Layout
Astro menggunakan file-based routing yang sangat intuitif:
---
// src/pages/blog/[...slug].astro
import { getCollection } from 'astro:content';
import Layout from '../../layouts/Layout.astro';
export async function getStaticPaths() {
const posts = await getCollection('posts');
return posts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
}
const { post } = Astro.props;
const { Content } = await post.render();
---
<Layout title={post.data.title}>
<article>
<h1>{post.data.title}</h1>
<Content />
</article>
</Layout>Insight Penting
1. Dramatic Bundle Size Reduction Pengurangan bundle size hingga 90% karena Astro tidak mengirim React runtime ke browser.
2. Faster Build Times Build time 4x lebih cepat karena Astro tidak perlu melakukan hydration dan optimasi JavaScript yang kompleks.
3. Better Core Web Vitals Semua metric Core Web Vitals berada di zona hijau, yang sangat penting untuk SEO.
Deployment ke Cloudflare Pages
Migrasi dari GitHub Pages ke Cloudflare Pages memberikan beberapa keuntungan:
Setup Cloudflare Pages
-
Connect Repository
- Login ke Cloudflare Dashboard
- Pilih Pages → Create a project
- Connect GitHub repository
-
Build Configuration
Build command: npm run build Build output directory: dist Root directory: / -
Custom Domain
- Tambahkan custom domain
minhphupham.com - Setup DNS records di Cloudflare
- Tambahkan custom domain
Keuntungan Cloudflare Pages
- Global CDN: Konten didistribusikan ke 200+ data center
- Automatic HTTPS: SSL certificate otomatis
- Preview Deployments: Setiap PR mendapat preview URL
- Analytics: Built-in web analytics
- Edge Functions: Serverless functions di edge (jika diperlukan)
Tips Optimasi Lanjutan
1. Image Optimization
---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.jpg';
---
<Image
src={heroImage}
alt="Hero image"
width={800}
height={400}
format="webp"
quality={80}
/>2. Preloading Critical Resources
---
// src/layouts/Layout.astro
---
<head>
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preconnect" href="https://fonts.googleapis.com">
</head>3. Service Worker untuk Caching
// public/sw.js
self.addEventListener('fetch', (event) => {
if (event.request.destination === 'image') {
event.respondWith(
caches.open('images').then((cache) => {
return cache.match(event.request).then((response) => {
return response || fetch(event.request).then((fetchResponse) => {
cache.put(event.request, fetchResponse.clone());
return fetchResponse;
});
});
})
);
}
});SEO Optimization
Structured Data
---
// src/components/StructuredData.astro
const { post } = Astro.props;
const structuredData = {
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": post.data.title,
"description": post.data.summary,
"author": {
"@type": "Person",
"name": "Minh Phu"
},
"datePublished": post.data.date.toISOString(),
"url": `https://minhphupham.com/blog/${post.slug}`
};
---
<script type="application/ld+json" set:html={JSON.stringify(structuredData)}></script>Meta Tags Optimization
<head>
<title>{seo.title}</title>
<meta name="description" content={seo.description}>
<meta name="keywords" content={seo.keywords.join(', ')}>
<link rel="canonical" href={seo.canonical}>
<!-- Open Graph -->
<meta property="og:title" content={seo.title}>
<meta property="og:description" content={seo.description}>
<meta property="og:url" content={seo.canonical}>
<meta property="og:type" content="article">
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content={seo.title}>
<meta name="twitter:description" content={seo.description}>
</head>Kesimpulan dan Rekomendasi
Kapan Sebaiknya Migrasi ke Astro?
✅ Pilih Astro jika:
- Blog atau website dengan konten mostly static
- Prioritas pada performa dan SEO
- Ingin build time yang cepat
- Tim kecil dengan fokus pada content
✅ Tetap dengan Next.js jika:
- Aplikasi web yang kompleks dengan banyak interaktivitas
- Memerlukan API routes dan server-side logic
- Tim besar dengan ekosistem React yang sudah established
- E-commerce atau dashboard yang memerlukan real-time updates
Lessons Learned
- “Right Tool for the Right Job”: Tidak ada framework yang sempurna untuk semua use case
- Performance Matters: Perbedaan performa yang signifikan berdampak pada user experience dan SEO
- Developer Experience: Astro memberikan DX yang excellent untuk static content
- Migration Strategy: Migrasi bertahap lebih aman daripada big bang approach
What’s Next?
Blog ini sekarang bisa diakses di minhphupham.com dengan performa yang jauh lebih baik. Link lama di pepryan.github.io/portfolio masih aktif, tapi semua update terbaru akan ada di domain baru.
Rencana Pengembangan
- Tutorial Series: Akan membuat series tutorial lengkap tentang Web, ataupun Cloud
- Performance Monitoring: Setup monitoring untuk tracking Core Web Vitals
- Content Strategy: Fokus pada konten teknis yang actionable
- Community Building: Sharing pengalaman di komunitas developer Indonesia
Jika kamu sedang mempertimbangkan migrasi serupa atau punya pertanyaan tentang proses ini, jangan ragu untuk reach out. Mari kita diskusi dan sharing pengalaman!
Artikel ini adalah bagian dari series “Web Development Journey” di mana saya sharing pengalaman hands-on dalam membangun dan mengoptimasi website. Stay tuned untuk tutorial dan insight lainnya!