LabHub

블로그

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

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

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

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

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

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

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

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

기존 React의 한계

SPA 시대 (2015-2022)

SSR + Hydration (2016-2023)

RSC (2023-)

RSC의 3가지 혁신

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

오해 vs 진실

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

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

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

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

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

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

주요 기능

(1) React 19 통합

(2) Partial Pre-Rendering (PPR)

(3) Turbopack 기본값

(4) Caching 전면 재설계

(5) Server Actions 성숙

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에 흡수됐다.

배경

React Router 7 핵심

(1) Framework Mode vs Library Mode

(2) RSC 점진적 지원

(3) Vite 기본

(4) loader/action

2025년 선택 기준

4장 · SvelteKit 2 · Svelte 5 Runes

Svelte는 다른 철학으로 성장.

Svelte 5의 변화

Runes (2024-2025)

예시:

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

SvelteKit 2 주요 기능

장점

단점

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

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

핵심 철학

SolidStart 1 (2024년 stable)

적합한 경우

한계

6장 · Astro 5 — Islands Architecture의 성숙

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

Astro 철학

Astro 5 (2024 말) 주요 기능

(1) Content Layer

(2) Server Islands

(3) View Transitions API

적합한 경우

한계

7장 · Qwik v2 — Resumability의 도전

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

핵심 개념: Resumability

장단점

장점

단점

2025년 위치

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년 현실적 선택 가이드

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

원칙 5가지

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

(2) 가장 아래 leaf에서 Client

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

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

(5) Client Boundary의 비용 인식

자주 헷갈리는 케이스

케이스 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>
  );
}

장점

주의 사항

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

Streaming

Partial Pre-Rendering (PPR)

사용 예

export const experimental_ppr = true;

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

2025년 표준화 경로

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

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

단계별 전략

Phase 1: 공존

Phase 2: 컴포넌트 분리

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

Phase 4: Layout·Loading·Error 재구성

Phase 5: API Routes → Server Actions

흔한 함정

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

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

"디자인 시스템은 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.

댓글

아직 댓글이 없습니다.

로그인하면 댓글을 쓸 수 있습니다