jaysnote
11분

그림으로 보는 Astro — 콘텐츠 웹 프레임워크는 어떻게 동작하는가

Astro의 핵심 개념(아일랜드 아키텍처, 빌드 타임 렌더링, 부분 하이드레이션, 산출물, 배포 단위, 정적 배포의 강점)을 여섯 장면의 그림과 해설로 풀어냅니다.

콘텐츠 중심 웹 프레임워크 Astro가 코드에서 화면까지 어떻게 동작하는지를, 여섯 장면의 그림과 해설로 천천히 따라가 봅니다. “빌드하면 결국 뭐가 나오는가?”, “정적 배포가 정말 강점인가?” 같은 질문에 답합니다.


들어가며

웹 프레임워크는 많습니다. 그중 Astro가 유독 사랑받는 이유는 단순합니다 — “읽기 위주의 콘텐츠 사이트” 를 만들 때, 가장 빠르고 가장 가벼운 결과물을 내놓기 때문입니다. 블로그, 문서, 마케팅 페이지, 포트폴리오처럼 내용을 보여주는 것이 핵심인 사이트라면 Astro는 거의 정답에 가깝습니다.

이 글은 여섯 장면(scene)으로 이루어집니다. 각 장면은 한 컷의 그림과, 그 그림이 말하는 내용을 풀어쓴 해설로 짝을 이룹니다.


Scene 1 — “Astro가 대체 뭐야?”

Scene 1 — Astro란 무엇인가

Astro는 콘텐츠 중심 웹사이트를 빠르게 만들기 위한 웹 프레임워크입니다. 이름처럼 “별(astro)“을 닮은 작은 로켓이 무거운 짐 없이 가볍게 떠오르는 모습을 상상하면 됩니다.

  • 블로그 · 문서 · 마케팅 · 포트폴리오처럼 내용이 주인공인 사이트에 특히 강합니다.
  • 가장 큰 특징 한 줄: 기본 JavaScript가 0kb — 즉, 필요 없는 곳엔 JS를 아예 보내지 않습니다.
  • React, Vue, Svelte, Solid, Preact 같은 UI 프레임워크를 한 프로젝트 안에서 섞어 쓸 수 있습니다.
---
// 컴포넌트 스크립트 (빌드 시 서버에서 실행됨)
const title = "안녕하세요";
---
<h1>{title}</h1>

.astro 파일은 위처럼 --- 사이에 JS/TS를 쓰고, 아래에 HTML을 작성하는 자체 컴포넌트 형식을 가집니다.


Scene 2 — 정적인 바다, 그리고 섬(Island)

Scene 2 — 아일랜드 아키텍처

Astro를 이해하는 열쇠는 아일랜드 아키텍처(Islands Architecture) 입니다.

정적인 HTML 바다 위에, 상호작용이 필요한 부분만 “섬” 처럼 떠 있게 만드는 방식.

한 페이지를 떠올려 보세요.

  • 정적인 부분 (90%): 제목, 본문, 헤더, 푸터, 이미지 → 한 번 그려지면 바뀔 일이 없습니다.
  • 동적인 부분 (10%): 검색창, 좋아요 버튼, 댓글, 다크모드 토글 → 사용자와 상호작용합니다.

기존 SPA(React, Vue 등)는 이 전부를 JavaScript로 만듭니다. 그래서 바뀌지도 않는 본문까지 JS로 다시 그리느라 무거운 번들을 통째로 내려받습니다.

아일랜드 아키텍처는 묻습니다 — “바뀌지도 않는 본문에 왜 JS가 필요하지?”

┌─────────────────────────────────────────┐
│  Header (정적 HTML)                      │
├─────────────────────────────────────────┤
│                          ╭─────────────╮ │
│  Article 본문            │ 🏝️ 검색창   │ │  ← 섬 (JS 동작)
│  (정적 HTML, JS 없음)    │ (인터랙티브) │ │
│                          ╰─────────────╯ │
│            ╭──────────────╮              │
│            │ 🏝️ 좋아요버튼 │             │  ← 섬 (JS 동작)
│            ╰──────────────╯              │
├─────────────────────────────────────────┤
│  Footer (정적 HTML)                      │
└─────────────────────────────────────────┘
   바다 = 정적 HTML (JS 0kb) · 🏝️ 섬 = 필요한 곳만 JS

두 가지 성질이 핵심입니다.

  1. 각 섬은 독립적이다. 검색창 섬과 좋아요 버튼 섬은 서로 모릅니다. 하나가 에러나도 다른 섬은 멀쩡합니다.
  2. 각 섬은 개별적으로 살아난다. 섬마다 언제 JS로 깨어날지를 따로 정할 수 있습니다 (다음 장면).

Scene 3 — 빌드할 때 모든 일이 끝난다

Scene 3 — 빌드 타임 렌더링

.astro 파일은 두 부분으로 나뉩니다.

---
// 🟦 [프론트매터] — 빌드 시 서버(Node)에서 "한 번만" 실행됨.
//    브라우저로는 절대 전송되지 않음.
const posts = await fetch('https://api.example.com/posts').then(r => r.json());
---
<!-- 🟩 [템플릿] — 실제 HTML로 변환되는 부분 -->
<ul>
  {posts.map(post => <li>{post.title}</li>)}
</ul>

가장 중요한 포인트:

  • --- 사이의 코드는 빌드할 때, 서버에서만 실행됩니다.
  • 그래서 API 키나 fetch한 원본 데이터가 브라우저로 새어나가지 않습니다.
  • 최종 결과는 데이터가 이미 박혀 있는 순수 HTML입니다.

npm run build를 하면 Astro는:

  1. src/pages/ 안의 각 파일을 하나의 URL(라우트)로 매핑하고
    src/pages/index.astro        →  /
    src/pages/blog/[slug].astro  →  /blog/어떤-글   (동적 라우트)
  2. 각 페이지의 프론트매터를 실행한 뒤
  3. 템플릿을 완성된 HTML 파일로 그려서
  4. dist/ 폴더에 떨궈둡니다.

이것이 SSG(Static Site Generation), Astro의 기본 모드입니다. 무거운 일은 빌드 때 미리 다 해두고, 브라우저엔 결과물(HTML)만 보냅니다.


Scene 4 — 섬이 깨어나는 순간 (부분 하이드레이션)

Scene 4 — client 지시어와 부분 하이드레이션

인터랙티브 컴포넌트는 기본적으로 HTML로만 그려집니다. 버튼은 보이지만 클릭은 안 됩니다 — JS가 없으니까요. 여기에 client:* 지시어를 붙이면, Astro는 그 컴포넌트만 따로 JS 조각으로 떼어내 브라우저에서 되살립니다(hydrate).

---
import Counter from '../components/Counter.jsx';  // React 컴포넌트
---
<Counter />                    <!-- ① JS 없는 정적 HTML -->
<Counter client:load />        <!-- ② JS 붙여서 동작 -->

②번의 동작 순서:

1. 브라우저가 HTML 받음 → Counter가 즉시 화면에 보임 (정적)
2. 백그라운드에서 Counter용 작은 JS 청크 다운로드
3. 그 JS가 해당 DOM 영역에만 React를 붙임 → 이제 클릭 동작

언제 깨어날지를 섬마다 지정합니다.

지시어동작 시점용도
client:load페이지 로드 즉시당장 필요한 UI (검색창)
client:idle브라우저가 한가할 때급하지 않은 UI
client:visible화면에 보일 때하단 댓글, 캐러셀
client:media={…}특정 화면 크기에서만모바일 전용 메뉴
client:only="react"서버 렌더 없이 클라이언트만SSR 불가 컴포넌트

client:visible을 쓰면, 사용자가 스크롤해서 그 영역이 보이기 전엔 JS를 다운로드조차 하지 않습니다. 이것이 성능의 비밀입니다.


Scene 5 — 빌드하면 결국 무엇이 나오는가

Scene 5 — 산출물과 배포 단위

질문: “빌드하면 결국 HTML이 나오는 거야?”네, 맞습니다.

정적 모드(output: 'static', 기본)에서 dist/는 이렇게 생깁니다.

dist/
├── index.html              ← / 페이지 (완성된 HTML)
├── about/index.html        ← /about
├── blog/first-post/index.html
├── _astro/                 ← 번들된 에셋 (해시 붙은 파일명)
│   ├── Counter.a1b2c3.js   ← 섬(인터랙티브)의 JS 조각
│   └── index.x7y8z9.css    ← 번들된 CSS
└── favicon.svg
  • *.html — 빌드 때 미리 렌더링된 완성형 HTML. 데이터가 이미 박혀 있습니다.
  • _astro/*.jsclient:*가 붙은 섬들의 JS만 쪼개진 조각. 섬이 없으면 JS는 0개입니다.
  • 브라우저는 Astro가 뭔지 전혀 모릅니다. 그냥 평범한 .html을 받습니다.

그렇다면 배포 단위는? 모드가 곧 배포 단위를 결정합니다.

output배포 단위배포 방식
static (기본)정적 파일 뭉치파일을 올리기만 하면 끝 (GitHub Pages, Netlify, S3, Cloudflare Pages…)
server서버 프로세스node ./dist/server/entry.mjs 처럼 실행해야 함
hybrid둘 다페이지별로 정적/동적 선택

여기서 헷갈리기 쉬운 지점 하나 — “어댑터”가 배포 단위의 모양을 바꿉니다. server/hybrid라도 어떤 어댑터를 쓰느냐에 따라 달라집니다.

어댑터실제 배포 단위
@astrojs/node내가 직접 띄우는 Node 프로세스 (Docker 등)
@astrojs/vercelVercel 서버리스 함수 (상시 서버 없음)
@astrojs/cloudflareCloudflare Worker

즉 “서버 모드”라도 서버리스로 배포하면, 내가 관리하는 상시 서버는 없고 요청이 올 때만 함수가 실행됩니다.


Scene 6 — 그래서, 정적 배포가 강점일까?

Scene 6 — 정적 배포의 강점과 결론

결론부터: 정적 배포는 그 자체로 만능 우위가 아니라, 사이트 성격이 정적에 맞을 때 비로소 강점이 됩니다.

정적 배포가 강점인 이유 ✅

강점
빠름서버 렌더링 없이 CDN이 완성된 HTML을 바로 던져줌 (전 세계 엣지에서 응답)
싸다/무료죽을 서버가 없으니 서버 비용 0
안 죽는다실행 프로세스가 없음 → 트래픽 폭주에도 다운 X
안전서버·DB가 없으니 공격 표면이 거의 없음
운영이 편함스케일링·패치할 서버가 없음. 그냥 파일

한계 ❌

  • 실시간성 없음 — 데이터가 바뀌면 다시 빌드해야 반영됩니다.
  • 개인화 어려움 — “로그인한 OO님 환영합니다” 같은 사용자별 화면은 서버 없이 불가합니다.
  • 서버 로직 부재 — 결제·인증·DB 쓰기는 정적만으론 못 합니다.

그래서 현대적 방식은 “정적을 기본으로 깔고, 동적 1%만 필요한 만큼 외부/함수로 떼어내기” 입니다.

정적 HTML (메인)  +  동적 1%는 외부에 위임
                       ├─ 댓글     → giscus / Disqus
                       ├─ 검색     → 클라이언트 JS or Algolia
                       ├─ 폼 전송  → 서버리스 함수 1개
                       └─ 인증     → 외부 인증 서비스

그리고 이것이 바로 Astro가 노리는 자리입니다.

정적의 강점(빠름·쌈·안전)은 누리되, 동적이 필요해지면 같은 프레임워크 안에서 server/hybrid로 자연스럽게 확장.

Hugo·Jekyll은 정적만 됩니다. Next.js는 동적에 무게를 둡니다. Astro는 “정적으로 시작해서 필요한 만큼만 동적으로” 를 한 도구로 풀어줍니다. 그래서 미리 정하지 못한 미래를 위한 여지를 남겨줍니다.


한 장으로 정리

  • Astro란? 콘텐츠 중심 웹 프레임워크. 기본 JS 0kb, UI 프레임워크 혼용 가능.
  • 아일랜드 아키텍처 — 정적 HTML 바다 + 인터랙티브 섬. 섬만 JS로 동작.
  • 동작 방식 — 빌드 때 서버에서 컴포넌트를 HTML로 렌더. --- 코드는 브라우저로 안 감.
  • 부분 하이드레이션client:*로 표시된 섬만, 지정한 타이밍에 깨어남.
  • 산출물 — 기본은 완성된 정적 HTML(+CSS+섬 JS 조각). 섬이 없으면 JS 0개.
  • 배포 단위 — 기본은 “파일을 올림”. server/hybrid면 서버 또는 서버리스 함수.
  • 정적의 강점 — 빠름·쌈·안 죽음·안전. 블로그엔 정적이 정답. 동적은 필요한 만큼만 확장.

블로그 같은 사이트라면 — 빌드 = 정적 HTML 생성이 맞고, 그게 곧 강점입니다. Astro는 “개발할 땐 컴포넌트로 편하게, 결과물은 빠른 정적 HTML로”가 핵심 철학입니다.

관련 글

← 목록으로