IT/nextjs 기초 내 공부

쉬운 NextJS 09: 컴포넌트의 필요성과 내부 동작 원리

higold 2024. 11. 12. 21:28
반응형

Next.js Link 컴포넌트의 필요성과 내부 동작 원리

목차

  1. 배경 지식
  2. 라우팅과 내비게이션 프로세스
  3. 코드 스플리팅
  4. 프리페칭
  5. Link 컴포넌트 vs Router.push
  6. 대안적 접근 방법

배경 지식

Next.js에서 라우팅과 내비게이션은 다음과 같이 구분됩니다:

  • 라우팅: URL 구성과 페이지 컴포넌트 연결
  • 내비게이션: 실제 페이지 간 이동 프로세스

라우팅과 내비게이션 프로세스

Next.js는 하이브리드 방식으로 라우팅과 내비게이션을 처리합니다:

// app/layout.tsx
import { Link } from 'next/link'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html>
      <body>
        <nav>
          <Link href="/products">Products</Link>
          <Link href="/about">About</Link>
        </nav>
        {children}
      </body>
    </html>
  )
}

코드 스플리팅

Next.js는 라우트 세그먼트를 기준으로 자동으로 코드 스플리팅을 수행합니다:

// app/products/page.tsx
export default function ProductsPage() {
  return (
    <div>
      <h1>Products Page</h1>
      {/* 이 페이지의 코드는 별도의 청크로 분리됨 */}
    </div>
  )
}

코드 스플리팅의 장점

  • 초기 로딩 시간 감소
  • 필요한 코드만 로드
  • 효율적인 캐싱

프리페칭

Link 컴포넌트의 가장 중요한 특징은 자동 프리페칭입니다:

// 프로덕션 환경에서 Link 컴포넌트 사용
import Link from 'next/link'

export default function Navigation() {
  return (
    <nav>
      <Link href="/products">
        Products {/* 자동으로 RSC 페이로드 프리페칭 */}
      </Link>
    </nav>
  )
}

RSC 페이로드 프리페칭

프로덕션 환경에서 Link 컴포넌트는 자동으로 다음을 수행합니다:

  1. 연결된 페이지의 RSC(React Server Component) 페이로드 프리페칭
  2. 필요한 자바스크립트 청크 프리로딩

Link 컴포넌트 vs Router.push

router.push를 사용할 때의 수동 프리페칭:

// pages/with-manual-prefetch.tsx
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'

export default function ManualPrefetch() {
  const router = useRouter()

  useEffect(() => {
    // 수동으로 프리페칭 구현
    router.prefetch('/products')
  }, [router])

  return (
    <button onClick={() => router.push('/products')}>
      Go to Products
    </button>
  )
}

대안적 접근 방법

Link 컴포넌트를 사용할 수 없는 경우의 대안:

// components/CustomNavigation.tsx
import { useRouter } from 'next/navigation'
import { useEffect } from 'react'

export default function CustomNavigation() {
  const router = useRouter()

  useEffect(() => {
    // 명시적 프리페칭
    router.prefetch('/target-route')
  }, [])

  const handleNavigation = () => {
    router.push('/target-route')
  }

  return (
    <button onClick={handleNavigation}>
      Navigate
    </button>
  )
}

프리페칭 최적화

import { useCallback, useEffect } from 'react'
import { useRouter } from 'next/navigation'

export function usePrefetch(route: string) {
  const router = useRouter()

  useEffect(() => {
    router.prefetch(route)
  }, [route, router])

  const navigate = useCallback(() => {
    router.push(route)
  }, [route, router])

  return navigate
}

성능 비교

  1. Link 컴포넌트 사용 시:
    • RSC 페이로드 크기: ~110 bytes
    • 자동 프리페칭
    • 최적화된 성능
  2. 수동 라우팅 사용 시:
    • RSC 페이로드 크기: ~1.7 KB
    • 명시적 프리페칭 필요
    • 추가적인 구현 필요

결론

Link 컴포넌트를 사용해야 하는 주요 이유:

  1. 자동 코드 스플리팅
  2. 효율적인 프리페칭
  3. 최적화된 RSC 페이로드 처리
  4. 향상된 사용자 경험

참고 문헌

  1. Next.js 공식 문서 - Routing
  2. Next.js 공식 문서 - Link Component
  3. React Server Components Specification
  4. Next.js GitHub Repository
  5. Vercel Blog - Understanding Next.js Navigation

태그

#NextJS #React #RouterNavigation #CodeSplitting #Prefetching #WebPerformance #JavaScript #TypeScript #RSC #ServerComponents #ClientComponents #WebDevelopment #Frontend

반응형