🌐 웹개발

Islands Architecture

아일랜드 아키텍처

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 스킵)

🗣️ 실무 대화 예시

💬 상황: 블로그 플랫폼 리뉴얼 기술 스택 논의

개발자 A "현재 블로그가 Next.js로 되어 있는데 Lighthouse 점수가 60점대에요. 대부분 정적 콘텐츠인데 JavaScript 번들이 300KB가 넘어요."
개발자 B "Islands Architecture 패턴을 적용하면 어떨까요? Astro로 마이그레이션하면 검색바, 댓글 같은 인터랙티브 부분만 하이드레이션하고 나머지는 순수 HTML로 제공할 수 있어요. 비슷한 사이트에서 JavaScript를 90% 줄이고 Lighthouse 95점 이상 달성한 사례가 있습니다."
개발자 A "기존 React 컴포넌트는 어떻게 하죠?"
개발자 B "Astro는 React, Vue, Svelte를 모두 같은 페이지에서 사용할 수 있어요. 기존 React 컴포넌트를 그대로 아일랜드로 가져오면 됩니다. client:visible 디렉티브로 스크롤해서 보이는 시점에만 로드하면 초기 로딩이 훨씬 빨라질 거예요."

⚠️ 주의사항

🔗 관련 용어

📚 더 배우기