Next.js의 병렬 라우팅과 일반 컴포넌트 방식 비교

1. 구현 방식 비교

일반적인 컴포넌트 방식:

// app/dashboard/page.tsx
import { Suspense } from 'react'

export default function Dashboard() {
  return (
    <div className="grid grid-cols-2 gap-4">
      <Suspense fallback={<div>Loading Dashboard...</div>}>
        <DashboardContent />
      </Suspense>

      <Suspense fallback={<div>Loading Analytics...</div>}>
        <AnalyticsContent />
      </Suspense>
    </div>
  )
}

async function DashboardContent() {
  const data = await fetchDashboardData()
  return <div>{/* 대시보드 내용 */}</div>
}

async function AnalyticsContent() {
  const data = await fetchAnalyticsData()
  return <div>{/* 분석 내용 */}</div>
}

병렬 라우팅 방식:

// app/@dashboard/page.tsx
export default async function Dashboard() {
  const data = await fetchDashboardData()
  return <div>{/* 대시보드 내용 */}</div>
}

// app/@analytics/page.tsx
export default async function Analytics() {
  const data = await fetchAnalyticsData()
  return <div>{/* 분석 내용 */}</div>
}

2. 주요 차이점

캐싱 메커니즘:

일반 컴포넌트 방식:

// 하나의 캐시 범위 내에서 동작
export default function Dashboard() {
  return (
    <div>
      <Suspense>
        <DashboardContent /> // 같은 캐시 범위 공유
        <AnalyticsContent /> // 같은 캐시 범위 공유
      </Suspense>
    </div>
  )
}

병렬 라우팅 방식:

// app/@dashboard/page.tsx - 독립적인 캐시 범위
export default async function Dashboard() {
  const data = await fetch('/api/dashboard', { next: { revalidate: 60 } })
  return <div>{/* ... */}</div>
}

// app/@analytics/page.tsx - 독립적인 캐시 범위
export default async function Analytics() {
  const data = await fetch('/api/analytics', { next: { revalidate: 3600 } })
  return <div>{/* ... */}</div>
}

주요 차이점

  1. 캐시 무효화 범위
// 일반 컴포넌트: 전체 페이지가 영향받음
revalidatePath('/dashboard')

// 병렬 라우팅: 개별 세그먼트만 영향받음  
revalidatePath('/dashboard/@analytics')
  1. 데이터 재사용
// 일반 컴포넌트
const data = await fetchData() // 한 번 fetch하면 페이지 내에서 재사용

// 병렬 라우팅
// @dashboard와 @analytics에서 같은 데이터를 fetch해도 
// 독립적으로 캐시되고 관리됨
  1. 메모리 사용
// 일반 컴포넌트  
const cache = new Map() // 하나의 캐시 공간

// 병렬 라우팅  
const dashboardCache = new Map() // 독립적인 캐시 공간  
const analyticsCache = new Map() // 독립적인 캐시 공간

3. 각 방식의 장단점

일반 컴포넌트 방식의 장점:

  • 더 단순한 파일 구조
  • 익숙한 컴포넌트 패턴
  • 컴포넌트 간 상태 공유가 더 쉬움
  • 더 유연한 레이아웃 조정 가능
  • 메모리 효율성이 좋음
  • 데이터가 자주 함께 업데이트되는 경우 적합

병렬 라우팅의 장점:

  • Next.js의 자동 코드 분할
  • 독립적인 에러 바운더리
  • 독립적인 로딩 상태
  • 섹션별 독립적인 캐싱 전략
  • 더 명확한 관심사 분리
  • 독립적인 데이터 갱신 주기가 필요할 때 적합

4. 선택 기준

일반 컴포넌트 방식이 적합한 경우:

  • 작은 규모의 프로젝트
  • 단순한 데이터 업데이트 패턴
  • 컴포넌트 간 긴밀한 상호작용이 필요한 경우
  • 메모리 효율성이 중요한 경우

병렬 라우팅이 적합한 경우:

  • 큰 규모의 프로젝트
  • 섹션별 독립적인 데이터 갱신이 필요한 경우
  • 섹션별 다른 에러 처리가 필요한 경우
  • 코드 분할이 중요한 경우

+ Recent posts