본문으로 건너뛰기
AI 도우미
🤖
안녕하세요! 프로그래밍 질문, 코드 설명, 블로그 글 검색 등을 도와드릴 수 있어요. 무엇이 궁금하신가요?
Enter를 누르거나 버튼을 클릭하여 전송 • Shift+Enter로 줄바꿈
Previous
Next
Astro Islands 아키텍처 완전 가이드 | 부분 Hydration으로 성능 극대화

Astro Islands 아키텍처 완전 가이드 | 부분 Hydration으로 성능 극대화

Astro Islands 아키텍처 완전 가이드 | 부분 Hydration으로 성능 극대화

이 글의 핵심

Astro의 혁신적인 Islands 아키텍처. 기본적으로 0 JavaScript를 전송하고, 필요한 컴포넌트만 선택적으로 Hydration합니다. React·Vue·Svelte를 한 페이지에서 동시에 사용할 수 있으며, Core Web Vitals를 크게 개선합니다.

이 글의 핵심

Astro Islands 아키텍처는 기본적으로 0 JavaScript를 전송하고, 필요한 컴포넌트만 선택적으로 Hydration합니다. React·Vue·Svelte를 동시에 사용할 수 있으며, 초기 JavaScript 크기를 90% 감소시켜 Core Web Vitals를 크게 개선합니다.

목차

Islands 아키텍처란?

Islands 아키텍처는 2019년 Katie Sylor-Miller가 제안한 부분 Hydration 패턴입니다.

🚀 핵심 개념

기존 SSR (Next.js, Nuxt)

서버:
- 전체 앱 HTML 생성

클라이언트:
- HTML 수신
- 전체 JavaScript 다운로드 (100KB+)
- 전체 앱 Hydration (500ms+)
→ 정적 콘텐츠도 Hydration (낭비!)

Islands 아키텍처 (Astro)

서버:
- HTML 생성

클라이언트:
- HTML 수신
- 인터랙티브 컴포넌트만 JavaScript 다운로드 (10KB)
- 해당 컴포넌트만 Hydration (50ms)
→ 정적 콘텐츠는 HTML만 유지

💡 Islands 비유

┌─────────────────────────────────┐
│                                 │
│   정적 HTML (바다)             │
│                                 │
│   ┌──────┐      ┌──────┐      │
│   │React │      │ Vue  │      │  ← Islands (인터랙티브)
│   │Counter│      │Chart │      │
│   └──────┘      └──────┘      │
│                                 │
│   정적 HTML (바다)             │
└─────────────────────────────────┘

Astro 시작하기

프로젝트 생성

# Astro 프로젝트 생성
npm create astro@latest my-astro-project

# 옵션 선택:
# - Template: Empty
# - Install dependencies: Yes
# - TypeScript: Yes (Strict)

cd my-astro-project
npm run dev

React 통합

# React 추가
npx astro add react

# 또는 수동 설치
npm install @astrojs/react
npm install react react-dom
// astro.config.mjs
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';

export default defineConfig({
  integrations: [react()],
});

Islands 사용법

기본 예제

---
// src/pages/index.astro
import Layout from '../layouts/Layout.astro';
import Counter from '../components/Counter.tsx';
---

<Layout title="Islands Demo">
  <h1>Welcome to Astro Islands</h1>
  
  <!-- 정적 HTML (JavaScript 없음) -->
  <p>This is static content with no JavaScript.</p>
  
  <!-- Island: 클라이언트에서 Hydration -->
  <Counter client:load />
  
  <!-- 다시 정적 HTML -->
  <p>More static content...</p>
</Layout>
// src/components/Counter.tsx
import { useState } from 'react';

export default function Counter() {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>
        Increment
      </button>
    </div>
  );
}

Client Directives (Hydration 전략)

1. client:load (즉시 로드)

<!-- 페이지 로드 즉시 Hydration -->
<Counter client:load />

사용 시기: 항상 보이는 중요한 컴포넌트 (헤더, 네비게이션)

2. client:idle (유휴 시 로드)

<!-- 브라우저가 유휴 상태일 때 Hydration -->
<ChatWidget client:idle />

사용 시기: 덜 중요한 위젯 (챗봇, 뉴스레터)

3. client:visible (보일 때 로드)

<!-- 뷰포트에 보일 때 Hydration -->
<LazyChart client:visible />

사용 시기: 스크롤해야 보이는 컴포넌트 (차트, 캐러셀)

4. client:media (미디어 쿼리)

<!-- 모바일에서만 Hydration -->
<MobileMenu client:media="(max-width: 768px)" />

사용 시기: 특정 화면 크기에서만 필요한 컴포넌트

5. client:only (SSR 건너뛰기)

<!-- 클라이언트에서만 렌더링 -->
<ThirdPartyWidget client:only="react" />

사용 시기: 서버에서 렌더링할 수 없는 컴포넌트


여러 프레임워크 동시 사용

React + Vue + Svelte

# 모든 프레임워크 설치
npx astro add react vue svelte
---
// src/pages/mixed.astro
import ReactCounter from '../components/ReactCounter.tsx';
import VueChart from '../components/VueChart.vue';
import SvelteCarousel from '../components/SvelteCarousel.svelte';
---

<Layout>
  <h1>Multi-Framework Page</h1>
  
  <!-- React 컴포넌트 -->
  <ReactCounter client:load />
  
  <!-- Vue 컴포넌트 -->
  <VueChart client:visible />
  
  <!-- Svelte 컴포넌트 -->
  <SvelteCarousel client:idle />
</Layout>

성능 측정

Before: React SSR (Next.js)

초기 JavaScript: 85KB (gzip)
Time to Interactive: 2.5초
Lighthouse Score: 75/100

After: Astro Islands

초기 JavaScript: 8KB (gzip)
Time to Interactive: 0.5초
Lighthouse Score: 98/100
→ JavaScript 90% 감소, TTI 80% 개선

실전 프로젝트: 블로그

페이지 구조

---
// src/pages/blog/[slug].astro
import Layout from '../../layouts/Layout.astro';
import TableOfContents from '../../components/TableOfContents.tsx';
import CommentSection from '../../components/CommentSection.tsx';
import ShareButtons from '../../components/ShareButtons.tsx';

const { slug } = Astro.params;
const post = await getPost(slug);
---

<Layout title={post.title}>
  <!-- 정적 콘텐츠 (JavaScript 0KB) -->
  <article>
    <h1>{post.title}</h1>
    <time>{post.date}</time>
    <div set:html={post.content} />
  </article>
  
  <!-- Island: TOC (보일 때 로드) -->
  <TableOfContents
    headings={post.headings}
    client:visible
  />
  
  <!-- Island: 공유 버튼 (유휴 시 로드) -->
  <ShareButtons
    title={post.title}
    url={post.url}
    client:idle
  />
  
  <!-- Island: 댓글 (보일 때 로드) -->
  <CommentSection
    postId={post.id}
    client:visible
  />
</Layout>

Astro vs Next.js vs Qwik

기능AstroNext.jsQwik
초기 JS0-10KB85KB1KB
Hydration부분 (Islands)전체Resumability
다중 프레임워크
SSG✅ 기본
SSR
학습 곡선🟢 쉬움🟡 중간🟡 중간
생태계🌿 성장 중🌳 성숙🌱 새로움

핵심 정리

Islands 아키텍처의 장점

  1. 압도적인 성능: 초기 JavaScript 90% 감소
  2. 선택적 Hydration: 필요한 부분만 인터랙티브
  3. 다중 프레임워크: React·Vue·Svelte 동시 사용
  4. SEO 최적화: 모든 콘텐츠가 정적 HTML
  5. Core Web Vitals: Lighthouse 점수 크게 향상

🚀 다음 단계


시작하기: npm create astro@latest로 5분 만에 프로젝트를 시작하고, Islands 아키텍처로 초고속 웹사이트를 만드세요! 🚀