Skip to content

✍️ 필사 모드: RSC 이후의 프론트엔드 2025 완전 정복: React Server Components 철학, Next.js App Router·Remix/React Router 7·SvelteKit·SolidStart·Astro Islands·Qwik Resumability 비교, 서버·클라이언트 경계 설계, 실전 마이그레이션 — Season 6 Ep 1

한국어
0%
정확도 0%
💡 왼쪽 원문을 읽으면서 오른쪽에 따라 써보세요. Tab 키로 힌트를 받을 수 있습니다.

프롤로그 · 프론트엔드는 다시 서버로 돌아왔다

1990년대 서버 렌더링(PHP·JSP) → 2010년대 SPA(React·Vue·Angular) → 2020년대 다시 서버 중심. 역사는 반복한다. 그러나 이번엔 다르다. 도구와 사고 방식이 완전히 새로워졌다.

2024-2025년 프론트엔드의 중심 질문은 하나다.

"서버와 클라이언트의 경계를 어디에 둘 것인가?"

React Server Components(RSC) 이후, 이 질문은 더 이상 피할 수 없다.

  • Next.js 15는 App Router가 완전히 정착
  • Remix는 React Router 7로 통합
  • SvelteKit 2는 Svelte 5 Runes와 함께 성숙
  • SolidStart 1(stable), Astro 5, Qwik v2
  • React 19은 Actions·use()·Ref as prop·document metadata 정식화

Season 6 첫 편은 이 전체 지형을 관통한다.

1장 · RSC의 본질 — "네트워크 경계를 컴포넌트 모델로"

기존 React의 한계

SPA 시대 (2015-2022)

  • 브라우저가 빈 HTML 받고, JS 번들 다운로드 후 렌더
  • 문제: 큰 번들 → 느린 초기 로딩, 나쁜 SEO, useEffect로 데이터 가져오기

SSR + Hydration (2016-2023)

  • 서버가 초기 HTML 생성, 클라이언트가 hydrate
  • 문제: 모든 JS를 여전히 전송, "useEffect 지옥"
  • 동일 로직을 서버·클라이언트 양쪽에 작성

RSC (2023-)

  • 컴포넌트를 Server Component / Client Component 로 분리
  • 서버 컴포넌트는 서버에서만 실행, JS 전송 안 됨
  • 클라이언트 컴포넌트만 hydrate
  • 데이터 가져오기는 서버 컴포넌트에서 await fetch() 자연스럽게

RSC의 3가지 혁신

  1. 번들 크기 절감: 라이브러리를 서버에서만 쓰면 클라이언트 번들에서 사라짐
  2. 데이터 Fetching 단순화: "어디서 데이터를 가져올까" 고민 종식, 컴포넌트에서 직접
  3. 네트워크 경계의 시각화: 'use client' 지시어로 경계 명시

오해 vs 진실

오해 1: "RSC = SSR의 새 이름이다"

  • 실제: 별개 개념. RSC는 SSR과 같이 쓰일 수도 있고, 없이 쓰일 수도 있음

오해 2: "모든 게 서버 컴포넌트여야 한다"

  • 실제: 상호작용이 있는 UI(폼·버튼 상태·애니메이션)는 클라이언트가 맞음

오해 3: "RSC는 Next.js 전용"

  • 실제: React의 공식 기능. Remix/React Router 7·Waku·다른 메타 프레임워크도 채택 중

오해 4: "성능이 무조건 좋아진다"

  • 실제: 경계 설계를 잘못하면 워터폴(순차 fetch) 발생, 오히려 느려짐

2장 · Next.js 15 App Router — 성숙한 RSC 구현체

2024년 내내 버그·불안정성 논란이 있었으나, Next.js 15(2024 10월)에서 대폭 안정화.

주요 기능

(1) React 19 통합

  • Actions, useFormStatus, useOptimistic 정식
  • use() hook으로 Promise·Context 언래핑

(2) Partial Pre-Rendering (PPR)

  • 정적 셸 + 동적 홀 하이브리드 렌더
  • 2025년 안정화 경로
  • 가장 혁신적 성능 아이디어

(3) Turbopack 기본값

  • Webpack 대체 러스트 번들러
  • Dev 서버 빌드 속도 5-10배

(4) Caching 전면 재설계

  • 이전의 "자동 캐싱"이 혼란 유발
  • 2025년엔 명시적 cache·revalidate 필요
  • use cache 지시어 도입 (실험)

(5) Server Actions 성숙

  • 폼 제출·뮤테이션을 서버 함수로
  • 'use server' 지시어

2025년 권장 구조

app/
  layout.tsx            # 전역 레이아웃 (RSC)
  page.tsx              #  (RSC)
  (marketing)/
    about/page.tsx      # 정적 마케팅
  (app)/
    dashboard/
      page.tsx          # 로그인 필요
      loading.tsx       # 로딩 UI
      error.tsx         # 에러 경계
      _components/
        ChartClient.tsx # 'use client'
  api/
    webhook/route.ts    # Route Handler

일반 실수 Top 5

  1. 'use client'를 과하게 씀 — 트리 최상단에 붙이면 전부 클라이언트
  2. Fetch를 클라이언트에서 반복 — 서버에서 한 번이면 충분
  3. Caching 가정 — Next.js 15부턴 명시적 opt-in 필요
  4. Server Action에서 무거운 로직 — 별도 API·큐 필요
  5. window 접근을 서버 컴포넌트에서 — 빌드 오류

3장 · Remix → React Router 7 통합

2024년 말 중대한 변화. Remix가 React Router 7에 흡수됐다.

배경

  • Remix는 항상 React Router 기반이었음
  • 유지 둘로 분리 관리 vs 통합
  • 2024년 5월 "Remix as React Router" 발표
  • 2024년 후반 React Router 7 릴리스

React Router 7 핵심

(1) Framework Mode vs Library Mode

  • Framework mode: 과거 Remix 방식 (파일 기반 라우팅·loaders·actions)
  • Library mode: 순수 라우팅 라이브러리
  • 양쪽 다 지원

(2) RSC 점진적 지원

  • 2025년 상반기 실험 단계, 후반 stable 목표
  • Remix 철학: "웹 플랫폼 표준 존중" 유지

(3) Vite 기본

  • Remix 2부터 Vite. RR7에서 공식 표준

(4) loader/action

  • 데이터 fetch·mutation 핸들러를 라우트별로
  • 서버 실행, JSON 반환

2025년 선택 기준

  • Next.js: SSG·ISR·PPR·전사 관리자 대시보드·마케팅 사이트까지 하나로
  • React Router 7 (Remix): 웹 표준 선호·간결한 로더·SPA도 지원
  • 두 가지를 한 조직에서 혼용하는 경우도 증가

4장 · SvelteKit 2 · Svelte 5 Runes

Svelte는 다른 철학으로 성장.

Svelte 5의 변화

Runes (2024-2025)

  • $state, $derived, $effect — 명시적 리액티비티
  • 이전의 마법적 문법 대체
  • Vue 3 Composition API, Solid Signals와 비슷한 추상화

예시:

<script>
  let count = $state(0);
  let doubled = $derived(count * 2);
  $effect(() => {
    console.log('count changed', count);
  });
</script>

SvelteKit 2 주요 기능

  • Vite 기본
  • load 함수 (서버·클라이언트)
  • Form Actions (Remix와 유사)
  • +page.server.ts 서버 전용
  • Adapter로 Vercel·Netlify·Cloudflare·Node·정적

장점

  • 번들 크기가 매우 작다 (React·Next.js 대비 1/3)
  • 문법 가독성 높음
  • 학습 곡선 완만
  • 빌트인 transitions·animations

단점

  • 생태계가 React 대비 작음
  • 엔터프라이즈 채용 시장 제한
  • 복잡한 상태관리 외부 의존

5장 · SolidStart 1 — 진정한 fine-grained reactivity

Solid는 React와 비슷한 JSX 문법, 전혀 다른 렌더링 모델.

핵심 철학

  • 컴포넌트는 단 1회 실행
  • Signals이 의존성 추적
  • Virtual DOM 없음
  • 극도의 성능 (공식 벤치마크 최상위)

SolidStart 1 (2024년 stable)

  • createSignal, createEffect, createResource
  • 파일 기반 라우팅
  • SSR·SPA·Static 모두 지원
  • Vinxi 빌드 툴 기반

적합한 경우

  • 극한 성능이 필요한 앱
  • React와 유사한 개발 경험 원하지만 번들·런타임 비용 싫은 경우
  • 복잡한 인터랙티브 UI (대시보드, 에디터)

한계

  • 생태계 소규모
  • 엔터프라이즈 도입 아직 제한
  • 일부 3rd party는 React/Vue에만 초점

6장 · Astro 5 — Islands Architecture의 성숙

"콘텐츠가 주인, 인터랙션은 섬(island)"

Astro 철학

  • 기본 렌더: 정적 HTML (JS 제로)
  • 필요한 컴포넌트만 섬(island) 으로 하이드레이트
  • 프레임워크 혼용: React + Vue + Svelte + Solid 같은 페이지에 가능
  • MDX·Markdown 네이티브 지원

Astro 5 (2024 말) 주요 기능

(1) Content Layer

  • 정적 콘텐츠 소스를 TypeScript로 정의
  • 블로그·문서 사이트 강력한 빌드 시간 처리

(2) Server Islands

  • 정적 페이지 안에 서버에서 동적 생성되는 부분 삽입
  • PPR과 유사한 개념

(3) View Transitions API

  • SPA 느낌의 전환을 MPA에 적용
  • 브라우저 네이티브 API 활용

적합한 경우

  • 블로그·문서·마케팅 사이트
  • SEO·성능이 절대적 중요
  • 여러 프레임워크 혼용 희망

한계

  • 복잡한 인터랙티브 앱(대시보드·에디터)에는 과부족
  • 클라이언트 라우팅은 옵션이지만 Next.js·Remix만큼 성숙 X

7장 · Qwik v2 — Resumability의 도전

2024-2025년 가장 이단적 접근.

핵심 개념: Resumability

  • Hydration 대신 Resumability
  • 서버가 HTML과 serialize된 앱 상태를 함께 보냄
  • 클라이언트는 필요한 순간에만 JS 로드·실행
  • 초기 로드 시 거의 JS 실행 0

장단점

장점

  • 초기 페이지 로드 극단적으로 빠름 (JS 거의 없음)
  • 대규모 앱도 첫 페이지는 작게

단점

  • 학습 곡선 높음
  • 생태계 매우 작음
  • 디버깅·툴링 아직 성숙 중

2025년 위치

  • Nike·Salesforce 등 일부 대형 채택
  • 일반 개발자 풀에선 여전히 니치
  • Builder.io가 주도 (모기업)

8장 · 메타 프레임워크 종합 비교표 (2025 4월)

기준Next.js 15RR7 (Remix)SvelteKit 2SolidStart 1Astro 5Qwik v2
렌더 모델RSC·SSR·SSG·PPRSSR·SPA·RSCSSR·SSG·SPASSR·SSG·SPAStatic+IslandsResumable
기본 언어React JSXReact JSXSvelteSolid JSXAnyQwik JSX
번들 크기중~대작음매우 작음최소최소
학습 곡선낮~중
생태계최대크다중간작음중간작음
엔터프라이즈★★★★★★★★★★★★★★★★★★★
콘텐츠 사이트★★★★★★★★★★★★★★★★★★★
대시보드 앱★★★★★★★★★★★★★★★★★★★★★★★
SEO★★★★★★★★★★★★★★★★★★★★★★★★★★★★
Edge/Serverless★★★★★★★★★★★★★★★★★★★★★★★★★

2025년 현실적 선택 가이드

  • 대규모 웹앱·엔터프라이즈: Next.js 15 (최대 생태계·안정성)
  • 웹 표준 선호, 복잡도 낮추고 싶다: React Router 7
  • 성능·번들이 생명: SvelteKit 2 or SolidStart 1
  • 블로그·마케팅·문서: Astro 5
  • 극단적 초기 로드 성능: Qwik v2

9장 · 서버·클라이언트 경계 설계 — 실전

원칙 5가지

(1) 기본은 서버 (Server-First)

  • 상호작용 없으면 서버 컴포넌트 유지
  • 'use client' 없이 시작

(2) 가장 아래 leaf에서 Client

  • "카운터 하나"를 위해 전체 페이지를 클라이언트로 만들지 마라
  • 'use client'는 가능한 트리의 잎

(3) 데이터는 서버에서 Fetch

  • await fetch()를 서버 컴포넌트에서 자유롭게
  • 클라이언트 useEffect fetch 지양

(4) 경계를 명확히 이름 짓기

  • Foo.server.tsx, Foo.client.tsx 네이밍 권장 (관례)
  • 읽는 사람이 바로 파악

(5) Client Boundary의 비용 인식

  • 'use client' 하나에 자식 전체 트리 클라이언트화
  • State·Effect·Browser API가 필요한 최소 단위로

자주 헷갈리는 케이스

케이스 1: 상태 없는 순수 UI 컴포넌트 → 서버. JS 전송 0.

케이스 2: 차트 라이브러리 래핑 → 클라이언트(시각화 라이브러리 대부분 brow서 API 사용).

케이스 3: 폼 → Server Action + 'use client' 래퍼 조합. useFormStatus로 진행 상태.

케이스 4: 테마 토글 → 클라이언트. 최소 단위로.

케이스 5: Auth 체크 후 다른 UI 보여주기 → 서버. await getServerSession() 후 분기.

10장 · Server Actions와 Forms — React 19의 혁신

기존 패턴

function Form() {
  const [state, setState] = useState();
  const handleSubmit = async (e) => {
    e.preventDefault();
    const res = await fetch('/api/submit', { method: 'POST', body: ... });
    setState(await res.json());
  };
  return <form onSubmit={handleSubmit}>...</form>;
}

새 패턴 (React 19 + RSC)

async function submitAction(formData: FormData) {
  'use server';
  const result = await db.insert(formData.get('name'));
  revalidatePath('/items');
}

export default function Page() {
  return (
    <form action={submitAction}>
      <input name="name" />
      <button type="submit">추가</button>
    </form>
  );
}

장점

  • Progressive Enhancement: JS 꺼져도 동작
  • 타입 안전: 같은 레포 서버·클라이언트 타입 공유
  • 보일러플레이트 감소: API 라우트·JSON 직렬화 불필요
  • 자동 revalidation: revalidatePath, revalidateTag

주의 사항

  • Public Internet 노출 엔드포인트임 → 인증·권한 체크 필수
  • 민감한 비밀을 클라이언트 코드에서 참조 금지
  • Error Handling과 Optimistic UI는 별도 설계

11장 · Streaming과 Partial Pre-Rendering (PPR)

Streaming

  • HTML을 한 번에 보내지 않고 조각씩 전송
  • 느린 부분은 <Suspense> 로 감싸 로딩 상태 먼저 보여주기
  • TTFB·LCP 개선

Partial Pre-Rendering (PPR)

  • 2024-2025 Next.js 신기능
  • 정적 셸을 빌드 시 생성
  • 동적 홀은 요청 시 채움
  • 최고의 초기 로드 + 개인화 공존

사용 예

export const experimental_ppr = true;

export default function Page() {
  return (
    <>
      <StaticHeader />                {/* 빌드 시 */}
      <Suspense fallback={<Skeleton/>}>
        <PersonalizedGreeting />       {/* 런타임 */}
      </Suspense>
      <StaticFooter />                 {/* 빌드 시 */}
    </>
  );
}

2025년 표준화 경로

  • Next.js 15 후반 stable 목표
  • React 팀과 협업하는 참조 구현
  • 다른 메타 프레임워크도 유사 기능 검토

12장 · 실전 마이그레이션 — Pages Router → App Router

2024년에도 많은 프로젝트가 Pages Router에서 App Router로 이동 중.

단계별 전략

Phase 1: 공존

  • app/pages/ 를 같이 운영 (Next.js 공식 지원)
  • 새 페이지만 App Router로

Phase 2: 컴포넌트 분리

  • 기존 컴포넌트에 'use client' 추가 → App Router에서도 동작
  • 상태·Effect 있는 것 위주

Phase 3: 데이터 가져오기 전환

  • getServerSideProps/getStaticProps → 서버 컴포넌트에서 fetch
  • SWR·React Query 의존 감축

Phase 4: Layout·Loading·Error 재구성

  • App Router의 특별 파일 활용
  • 중첩 레이아웃 설계

Phase 5: API Routes → Server Actions

  • 단순 mutation은 Server Action으로
  • 외부 노출 API는 Route Handler 유지

흔한 함정

  • use client 트리 최상단: 번들 폭발, 성능 저하
  • 데이터 가져오기 중복: 서버·클라이언트 양쪽에서
  • 캐시 이해 부족: Next.js 15 캐시 정책 대폭 변경
  • Edge Runtime 가정: Node API 쓰는 코드가 Edge에서 깨짐
  • Hydration Mismatch: 서버·클라이언트 렌더 결과 다름 → 콘솔 에러

13장 · 다음 글 예고 — Season 6 Ep 2: "디자인 시스템과 토큰의 현재"

프레임워크 골격을 만들었다면 다음은 비주얼과 인터랙션. Ep 2는 디자인 시스템.

  • Radix UI·shadcn/ui·Chakra·Tamagui·DaisyUI·Park UI·Ark UI 비교
  • Headless vs Styled 철학
  • Design Token 표준 (W3C Design Tokens)
  • Figma ↔ Code 연동 (Tokens Studio, Figma Variables, Specify)
  • 컴포넌트 API 설계 원칙
  • Theming·Dark Mode·Color Mode
  • 접근성(Accessibility) 기본값
  • 모바일·데스크톱 크로스 디자인
  • 대기업 디자인 시스템 사례 (토스·네이버·카카오·쿠팡)
  • 팀 규모별 디자인 시스템 도입 전략

"디자인 시스템은 CSS가 아니다. 제품 팀의 공용 언어다."

다음 글에서 만나자.

에필로그 · 체크리스트 12

  1. 우리 프로젝트가 2025년 메타 프레임워크 중 적절한 것을 선택했는가?
  2. 서버·클라이언트 경계가 의식적으로 설계되어 있는가?
  3. 'use client'가장 아래 leaf에만 붙어 있는가?
  4. Server Action으로 mutation이 처리되는가?
  5. Streaming·Suspense로 느린 부분이 격리되어 있는가?
  6. PPR 또는 동등한 정적+동적 하이브리드를 활용하는가?
  7. Core Web Vitals (LCP/CLS/INP) 를 측정하고 있는가?
  8. Hydration Mismatch가 없는가?
  9. 데이터 Fetching이 서버에서 한 곳으로 정리되어 있는가?
  10. Edge Runtime·Node Runtime이 의도적으로 선택되었는가?
  11. 번들 크기를 정기 모니터링(Bundle Analyzer)하고 있는가?
  12. Pages Router 잔재가 있다면 마이그레이션 계획이 있는가?

"프론트엔드는 다시 서버로 돌아왔지만, 돌아온 서버는 예전의 서버가 아니다."

Season 6가 시작됐다. 다음 편에서 만나자.

— Season 6 Ep 1, Fin.

현재 단락 (1/304)

1990년대 서버 렌더링(PHP·JSP) → 2010년대 SPA(React·Vue·Angular) → 2020년대 다시 **서버 중심**. 역사는 반복한다. 그러나 이번엔 다르다....

작성 글자: 0원문 글자: 8,481작성 단락: 0/304