Files
2nd/10_Wiki/Topics/AI_and_ML/Next.js.md
T

15 KiB

category, tags, title, description, last_updated
category tags title description last_updated
AI_and_ML
auto-wikified
technical-documentation
merged
ai_and_ml
Next.js **Next. 2026-05-04

Next.js

📌 Brief Summary

Next.js는 유연한 렌더링 전략(SSR, SSG 등), 내장 API 라우트 및 풀스택 기능을 지원하여 복잡한 애플리케이션의 성능과 확장성을 높여주는 React 기반의 메타 프레임워크입니다 [1, 2]. 특히, App Router 아키텍처를 통해 **React Server Components(RSC)**를 선도적으로 도입함으로써 클라이언트로 전송되는 자바스크립트 번들 크기를 줄이고, 데이터 페칭과 UI 렌더링 성능을 획기적으로 최적화하는 데 핵심적인 역할을 하고 있습니다 [3-5].

📖 Core Content

  • 서버 컴포넌트(RSC) 중심의 App Router 아키텍처: Next.js의 새로운 "app 디렉토리" 내에 있는 라우트와 컴포넌트들은 기본적으로 서버 컴포넌트로 동작합니다 [4]. 이는 서버에서만 비동기적으로 실행되어 데이터를 직접 가져오며, 그 결과물을 직렬화된 형태(RSC 페이로드)로 클라이언트에 전달하므로 자바스크립트 번들 크기에 영향을 주지 않습니다 [6-9].
  • 클라이언트 컴포넌트와의 경계 설정 및 혼합(Interleaving): 사용자 상호작용(이벤트 핸들러)이나 브라우저 전용 API, 상태(useState 등)가 필요한 경우, 최상단에 "use client" 지시어를 선언하여 클라이언트 컴포넌트로 만듭니다 [4, 10]. Next.js에서는 클라이언트 컴포넌트 내부에 서버 컴포넌트를 직접 렌더링할 수는 없으나, 서버 컴포넌트를 children과 같은 Prop(직렬화 가능한 속성) 형태로 전달하여 자연스럽게 중첩(Interleaving)할 수 있습니다 [11, 12].
  • 스트리밍(Streaming)과 Suspense 통합: 긴 시간이 소요되는 데이터 로딩이 전체 페이지 렌더링을 차단하지 않도록, Next.js는 RSC를 <Suspense> 경계와 함께 사용하여 아웃 오브 오더(Out-of-order) 방식의 스트리밍 렌더링을 제공합니다 [3, 13]. 서버는 HTML 셸을 먼저 빠르게 보내고, 데이터가 준비되는 대로 나머지 RSC 페이로드를 클라이언트 측에 청크 단위로 스트리밍하여 즉각적인 로딩 UI(Fallback)에서 실제 콘텐츠로 전환합니다 [14-16].
  • 서버 액션(Server Actions)을 통한 데이터 변이: "use server" 지시어로 정의되는 서버 액션을 사용하면, 클라이언트 컴포넌트의 버튼 클릭 등 이벤트 핸들러에서 직접 서버의 함수를 호출하여 데이터를 업데이트할 수 있습니다 [6, 17, 18]. 이는 클라이언트와 서버 간의 단일 라운드트립만으로 네트워크 요청, 데이터베이스 변경, 그리고 revalidateTag를 통한 최신 UI의 재검색 및 반영을 완료할 수 있게 해줍니다 [18].
  • React-Query 등 외부 라이브러리와의 결합: 서버 액션 및 캐싱 전략만으로는 대응하기 까다로운 다중 폼 상태 관리 및 동적 라우팅 조건에서는 @tanstack/react-queryuseSuspenseQuery 등과 RSC를 조합하여 초기 데이터는 서버에서 가져오고 후속 인터랙션과 데이터 동기화는 클라이언트에서 효율적으로 관리하는 패턴이 유용하게 사용됩니다 [19-21].

⚖️ Trade-offs & Caveats

  • 서버 액션의 직렬화와 캐시 무효화(revalidateTag) 비용: 서버 액션 내에서 revalidateTag를 호출할 경우, 변경된 일부 데이터만 로드되는 것이 아니라 현재 페이지의 전체 RSC 트리가 다시 렌더링되고 모든 관련 데이터를 다시 요청하는 비효율이 발생합니다 [22, 23]. 또한, 서버 액션은 직렬(Serial)로만 실행되어 한 번에 하나의 액션만 처리 가능하므로 네트워크 상태가 불량한 상황에서 연속된 호출 시 병목이 발생할 수 있습니다 [24].
  • 공개 HTTP 엔드포인트로서의 보안 위험 (React2Shell): "use server" 지시어가 붙은 서버 액션은 내부 함수처럼 보이지만 실제로는 전 세계 누구나 접근할 수 있는 공개 HTTP 엔드포인트입니다 [25]. 일반적인 API 라우트와 동일한 수준의 입력값 검증과 권한 확인(Sanitization)을 거치지 않으면 원격 코드 실행(RCE) 등 치명적인 보안 취약점에 노출될 수 있습니다 [25-27]. 또한, 서버 컴포넌트에서 클라이언트로 넘기는 프로프에 필요 이상의 데이터를 넘기면 브라우저 네트워크 탭에 그대로 노출되므로 데이터 최소화가 필수적입니다 [28].
  • 복잡도 증가와 에코시스템 종속성: 클라이언트/서버 컴포넌트 간의 혼합과 중첩 사용은 애플리케이션의 구조적 복잡성을 크게 높입니다 [29]. 또한, 무분별하게 모든 곳에 "use client"를 붙이는 이른바 "Vibe Coding"의 함정에 빠지면 RSC의 혜택인 번들 최적화 효과는 사라지고 구조적 복잡성과 보안 표면만 늘어나게 됩니다 [30, 31]. 현재 RSC를 온전히 프로덕션에 지원하는 프레임워크가 사실상 Next.js(Vercel)에 종속되어 있으며, emotion과 같은 CSS-in-JS 라이브러리와 호환성 문제가 발생하는 등 기술 부채의 위험도 존재합니다 [32].
  • 라우팅 동작 시의 불필요한 서버 요청 문제: 클라이언트에서 URL 쿼리 문자열이 변경될 때(router.push 사용 시), Next.js는 변경 사항이 없는 RSC 페이지조차 새로 렌더링하도록 동작하여 불필요한 네트워크 대기 시간을 발생시킬 수 있으며, 이를 우회하기 위해 window.history.pushState를 사용할 경우 Suspense 전환과 매끄럽게 연동되지 않아 UI 경험이 저하되는 제약이 있습니다 [33, 34].

Last updated: 2026-05-03

📚 Legacy Insights & Additional Context

Note

Below is content merged from previous versions of this documentation.

📌 Brief Summary

Next.js 기반 대규모 웹 애플리케이션은 비즈니스 로직과 UI를 체계적으로 분리하는 기능 및 도메인 중심(Feature-Driven/Domain-Driven)의 모듈형 아키텍처를 채택하여 장기적인 유지보수성과 확장성을 확보하는 현대적인 웹 개발 방식입니다 [1, 2]. 특히 최근의 Next.js App Router 환경에서는 React Server Components(RSC)와의 호환성 문제로 인해 런타임 오버헤드가 있는 CSS-in-JS 대신 Tailwind CSS, CSS Modules, 또는 zero-runtime 방식의 CSS-in-JS(vanilla-extract 등)와 같은 정적 스타일링 전략을 선택하는 것이 필수적입니다 [3-5]. 이러한 구조와 스타일링 접근은 팀 간의 협업을 돕고 기술 부채를 최소화하여, 대규모 프로젝트에서도 "예쁘게"가 아닌 "유지보수 가능한" 시스템을 구축할 수 있게 합니다 [1, 5, 6].


Next.js 렌더링 최적화는 애플리케이션의 성능, SEO 및 사용자 경험을 극대화하기 위해 페이지 특성에 맞춰 다양한 렌더링 전략(SSR, SSG, CSR, ISR)을 조합하여 사용하는 과정을 의미합니다 [1-3]. 특히 [React Server Components|React Server Components]를 활용하여 서버에서 렌더링과 데이터 페칭을 처리함으로써 클라이언트로 전송되는 자바스크립트 번들의 크기를 대폭 줄입니다 [4, 5]. 이를 통해 초기 로딩 속도(LCP)를 개선하고 부드러운 상호작용을 보장하는 것이 핵심 목적입니다 [6-8].

📖 Core Content

  • 기능 및 도메인 중심 아키텍처 (Feature-Driven Architecture): 대규모 Next.js 프로젝트가 성장함에 따라 컴포넌트, 훅, 비즈니스 로직을 파일 유형별로 단순 그룹화하거나 라우팅을 담당하는 app/ 디렉토리에 모두 넣는 것은 관리를 불가능하게 만듭니다 [1]. 이를 해결하기 위해 실제 도메인(예: market-data, user-profile, auth)을 기반으로 하는 기능 중심의 폴더 구조(예: src/features/...)를 도입해야 합니다 [1, 2]. app/ 디렉토리 내의 파일(page.tsx, layout.tsx 등)은 라우팅과 레이아웃 등 최소한의 역할만 수행하게 하고, 실제 비즈니스 로직과 UI 컴포넌트는 features/ 하위로 위임하여 코드를 캡슐화합니다 [2, 7].

  • Next.js App Router와 CSS 아키텍처 전략: 대규모 Next.js 애플리케이션, 특히 App Router를 사용하는 프로젝트에서 기존의 CSS-in-JS(styled-components, Emotion 등)는 브라우저에서 런타임에 CSS를 생성하여 성능을 저하시킬 뿐만 아니라, React [Server Components|Server Components]에는 Context가 존재하지 않아 본질적으로 호환되지 않는 문제를 발생시킵니다 [3, 4]. 따라서 2025년 기준 대규모 프로젝트에서는 런타임 비용이 없는 Tailwind CSS나 CSS Modules를 사용하거나, 빌드 타임에 정적 CSS를 생성하는 vanilla-extract를 사용하는 것이 권장됩니다 [4, 5, 8]. 특히 다중 테마가 필요한 대규모 디자인 시스템에서는 런타임 오버헤드 없이 타입 안정성을 제공하는 vanilla-extract가 가장 이상적입니다 [5].

  • 유지보수성을 위한 프로젝트 구조화 규칙:

    • 디렉토리 및 경로 관리: 초기 프로젝트 설정 시 src/ 디렉토리를 사용하여 tailwind.config.ts, next.config.mjs 등의 루트 설정 파일과 소스 코드를 물리적으로 분리합니다 [9]. 또한, 중첩된 상대 경로(../../../)로 인한 혼란을 막기 위해 @/components/...와 같은 절대 경로 임포트(Absolute Imports)를 강제해야 합니다 [6, 9, 10].
    • 관심사 분리 ([[뇌와 팔다리의 분리 - 관심사의 분리 (Separation of Concerns)|Separation of Concerns]]): 데이터 패칭이나 API 호출 같은 네트워크 로직은 UI 컴포넌트와 분리하여 별도의 레이어(예: services/ 폴더)에서 관리해야 백엔드 변경이나 유지보수에 유연하게 대응할 수 있습니다 [2, 11].
    • 확장성 도구 활용: 대규모 시스템의 경우 Storybook을 통해 재사용 가능한 UI 컴포넌트 시스템을 구축하여 일관성을 높이고, 여러 앱과 공유 패키지를 효과적으로 관리하기 위해 Turborepo나 Nx와 같은 Monorepo 도구를 도입하는 것이 권장됩니다 [6, 11].

  • 하이브리드 렌더링 전략 (Hybrid Rendering): Next.js는 동일한 애플리케이션 내에서 페이지별 요구사항에 따라 렌더링 방식을 유연하게 혼합할 수 있습니다 [1, 2]. 마케팅 페이지나 공식 문서에는 정적 사이트 생성(SSG)을, 항상 최신 상태를 유지해야 하는 상품 페이지에는 서버 사이드 렌더링(SSR)을, 사용자 대시보드와 같이 인터랙션이 중요한 곳에는 클라이언트 사이드 렌더링(CSR)을 적용하여 성능과 SEO를 최적화합니다 [1, 3].
  • 점진적 정적 재생성 (ISR): 정적 생성(SSG)의 압도적인 로딩 속도와 SSR의 데이터 최신화 이점을 결합한 모델입니다 [9, 10]. 전체 사이트를 다시 빌드할 필요 없이 특정 시간 간격이나 요청에 따라 백그라운드에서 개별 정적 페이지를 업데이트하여 최신 상태의 캐시된 콘텐츠를 제공합니다 [10-12].
  • React Server Components (RSC) 생태계 도입: Next.js의 App Router는 기본적으로 컴포넌트를 서버 컴포넌트로 처리합니다 [13]. 정적인 UI는 서버에서 렌더링 되어 HTML과 직렬화된 명령(React Flight 프로토콜)으로만 전달되며, 브라우저로 전송되는 자바스크립트(0 bytes)를 줄여 성능을 크게 향상시킵니다 [4, 5, 14-16]. 인터랙션이 필수적인 부분만 "use client" 지시어를 사용해 클라이언트 컴포넌트로 분리합니다 [14, 17, 18].
  • 데이터 페칭과 병렬 처리: 서버 컴포넌트를 사용하면 API 계층을 거칠 필요 없이 데이터베이스나 로컬 파일 시스템에서 직접 데이터를 가져올 수 있습니다 [14, 19, 20]. 이를 적절히 설계하면 렌더링 중 부모와 자식 컴포넌트가 독립적으로 데이터를 병렬 호출할 수 있어, 네트워크 워터폴(Waterfall) 현상을 제거하고 응답 속도를 최소화합니다 [21, 22].
  • 자동화된 최적화 도구 활용: next/image 컴포넌트는 이미지 포맷 자동 변환(WebP/AVIF), 반응형 사이징, 그리고 화면에 보일 때만 이미지를 로드하는 지연 로딩(Lazy Loading)을 지원하여 Core Web Vitals를 향상시킵니다 [7, 23, 24]. 추가로 최신 Next.js 환경에서는 React Compiler를 설정하여 수동 메모이제이션 없이 렌더링 최적화를 자동화할 수도 있습니다 [25].

⚖️ Trade-offs & Caveats

No trade-offs available.

🔗 Knowledge Connections

  • Related Topics: Feature-Driven Architecture, React Server Components (RSC), Tailwind CSS, CSS Modules, Zero-Runtime CSS-in-JS
  • Projects/Contexts: Next.js App Router 기반 프로젝트 환경, 대규모 엔터프라이즈 프론트엔드 시스템
  • Contradictions/Notes: 소스에 따르면, 과거에는 동적 스타일링과 테마 적용의 이점 때문에 CSS-in-JS(styled-components, Emotion 등)가 널리 사용되었으나, 최근 Next.js의 App Router 및 RSC 환경의 도입으로 인해 컨텍스트(Context) 기반의 런타임 CSS-in-JS는 작동하지 않거나 심각한 성능 오버헤드를 유발하여 사용이 지양되고 있습니다. 그 대안으로 Tailwind CSS나 CSS Modules 같은 정적 렌더링 호환 스타일링 방식이 새로운 표준으로 자리 잡았습니다 [3-5].

Last updated: 2026-04-26


  • Related Topics: React Server Components, 점진적 정적 재생성 (ISR), 하이드레이션 (Hydration
  • Projects/Contexts: Next.js App Router, 전자상거래 플랫폼 (E-commerce Platforms
  • Contradictions/Notes: SSR은 초기 콘텐츠 렌더링(FCP)이 빠르고 SEO에 매우 유리하지만, 자바스크립트를 로드하고 연결하는 '하이드레이션(Hydration)' 과정을 거쳐야 하므로 사용자가 페이지와 상호작용하기까지의 시간(TTI)이 지연될 수 있습니다 [8, 26-28]. 또한, 서버 컴포넌트를 사용하더라도 데이터 의존성이 직렬(Sequential)로 연결되어 있다면 브라우저가 아닌 서버 측에서 워터폴 현상이 발생해 응답 지연이 생길 수 있으므로 병렬 처리를 고려한 설계가 필요합니다 [29, 30].

Last updated: 2026-04-25