Islands Architecture
아일랜드 아키텍처
Islands Architecture는 정적 HTML 페이지 내에 인터랙티브한 컴포넌트(아일랜드)를 독립적으로 하이드레이션하는 웹 아키텍처 패턴입니다. Astro, Fresh, Marko 등에서 채택되어 뛰어난 초기 로딩 성능과 선택적 JavaScript 로딩을 제공합니다.
아일랜드 아키텍처
Islands Architecture는 정적 HTML 페이지 내에 인터랙티브한 컴포넌트(아일랜드)를 독립적으로 하이드레이션하는 웹 아키텍처 패턴입니다. Astro, Fresh, Marko 등에서 채택되어 뛰어난 초기 로딩 성능과 선택적 JavaScript 로딩을 제공합니다.
Islands Architecture는 2019년 Katie Sylor-Miller가 처음 명명하고, 2021년 Jason Miller(Preact 창시자)가 본격적으로 대중화한 웹 아키텍처 패턴입니다. "정적 HTML의 바다에 떠 있는 인터랙티브 아일랜드"라는 비유에서 이름이 유래했으며, 페이지 대부분은 정적 HTML로 제공하고 인터랙션이 필요한 부분만 선택적으로 JavaScript를 로드합니다.
전통적인 SPA(Single Page Application)는 전체 페이지를 JavaScript로 하이드레이션하여 초기 로딩이 느리고 TTI(Time to Interactive)가 지연됩니다. Islands Architecture는 각 인터랙티브 컴포넌트를 독립적인 "아일랜드"로 취급하여, 필요한 부분만 개별적으로 하이드레이션합니다. 이로 인해 대부분의 정적 콘텐츠는 즉시 렌더링되고, JavaScript는 점진적으로 로드됩니다.
Astro는 Islands Architecture의 대표 프레임워크로, `client:load`, `client:idle`, `client:visible` 같은 디렉티브로 하이드레이션 시점을 세밀하게 제어할 수 있습니다. Deno의 Fresh는 기본적으로 Zero JavaScript를 지향하며, Marko는 자동으로 최적의 아일랜드를 생성합니다. Qwik은 Resumability라는 개념으로 하이드레이션 자체를 제거합니다.
Islands Architecture는 콘텐츠 중심 웹사이트(블로그, 문서, 마케팅 페이지)에 특히 적합합니다. 전체 JavaScript 번들 크기를 90% 이상 줄일 수 있고, Core Web Vitals 점수를 크게 개선합니다. 다만 복잡한 상태 공유가 필요한 애플리케이션에는 적합하지 않을 수 있으며, 아일랜드 간 통신에는 추가적인 설계가 필요합니다.
// Astro에서 Islands Architecture 사용 예제
// src/pages/index.astro
---
// 서버에서 실행되는 컴포넌트 스크립트
import Layout from '../layouts/Layout.astro';
import Header from '../components/Header.astro'; // 정적 컴포넌트
import Footer from '../components/Footer.astro'; // 정적 컴포넌트
// React/Vue/Svelte 등 인터랙티브 컴포넌트
import SearchBar from '../components/SearchBar.jsx';
import Newsletter from '../components/Newsletter.vue';
import Comments from '../components/Comments.svelte';
const posts = await fetch('/api/posts').then(r => r.json());
---
<Layout title="블로그">
<!-- 정적 HTML - JavaScript 없음 -->
<Header />
<main>
<!-- 아일랜드 1: 페이지 로드 시 즉시 하이드레이션 -->
<SearchBar client:load placeholder="검색어를 입력하세요" />
<!-- 정적 콘텐츠 -->
<section class="posts">
{posts.map((post) => (
<article>
<h2>{post.title}</h2>
<p>{post.excerpt}</p>
</article>
))}
</section>
<!-- 아일랜드 2: 브라우저가 idle 상태일 때 하이드레이션 -->
<Newsletter client:idle />
<!-- 아일랜드 3: 뷰포트에 보일 때 하이드레이션 (Lazy) -->
<Comments client:visible postId={posts[0].id} />
</main>
<!-- 정적 HTML - JavaScript 없음 -->
<Footer />
</Layout>
// 클라이언트 디렉티브 옵션:
// client:load - 페이지 로드 시 즉시 (높은 우선순위)
// client:idle - 브라우저 idle 시 (requestIdleCallback)
// client:visible - 뷰포트에 보일 때 (IntersectionObserver)
// client:media - 미디어 쿼리 충족 시
// client:only - 클라이언트에서만 렌더링 (SSR 스킵)
💬 상황: 블로그 플랫폼 리뉴얼 기술 스택 논의