icon안동민 개발노트

코드 분할 및 지연 로딩


 Next.js는 애플리케이션의 성능을 최적화하기 위한 강력한 코드 분할 및 지연 로딩 기능을 제공합니다.

 이 절에서는 자동 코드 분할, 동적 임포트를 사용한 컴포넌트 지연 로딩, 그리고 이들이 애플리케이션 성능에 미치는 영향에 대해 알아보겠습니다.

자동 코드 분할

 Next.js는 기본적으로 각 페이지와 라우트에 대해 자동 코드 분할을 수행합니다. 이는 초기 로드 시간을 줄이고 필요한 코드만 로드하여 애플리케이션의 성능을 향상시킵니다.

동적 임포트 사용법

 동적 임포트를 사용하면 컴포넌트나 모듈을 필요한 시점에 로드할 수 있습니다.

import dynamic from 'next/dynamic'
 
const DynamicComponent = dynamic(() => import('../components/DynamicComponent'))
 
export default function Home() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <DynamicComponent />
    </div>
  )
}

Suspense와 함께 사용하기

 React의 Suspense를 사용하여 동적으로 임포트된 컴포넌트의 로딩 상태를 관리할 수 있습니다.

import { Suspense } from 'react'
import dynamic from 'next/dynamic'
 
const DynamicComponent = dynamic(() => import('../components/DynamicComponent'), {
  loading: () => <p>Loading...</p>,
  suspense: true,
})
 
export default function Home() {
  return (
    <div>
      <h1>Welcome to my app</h1>
      <Suspense fallback={<p>Loading...</p>}>
        <DynamicComponent />
      </Suspense>
    </div>
  )
}

라우트 기반 코드 분할의 이점

 Next.js의 App Router는 각 라우트에 대해 자동으로 코드를 분할합니다. 이는 다음과 같은 이점을 제공합니다.

  1. 초기 로드 시간 감소
  2. 필요한 코드만 다운로드하여 대역폭 절약
  3. 전체 애플리케이션 성능 향상

성능 모니터링 도구 사용법

 Next.js는 내장된 성능 분석 도구를 제공합니다. next/serverwithPerformanceMetrics 미들웨어를 사용하여 서버 사이드 성능을 모니터링할 수 있습니다.

// middleware.js
import { withPerformanceMetrics } from 'next/server'
 
export default withPerformanceMetrics((req) => {
  // Your middleware logic here
})

 클라이언트 사이드에서는 React DevTools와 Chrome DevTools의 Performance 탭을 사용하여 성능을 분석할 수 있습니다.

7장 서버, 클라이언트 컴포넌트와의 연결

 코드 분할과 지연 로딩은 7장에서 다룬 서버 컴포넌트와 클라이언트 컴포넌트 개념과 밀접하게 연관됩니다. 서버 컴포넌트는 자동으로 코드 분할되어 클라이언트로 전송되는 JavaScript 양을 줄입니다. 반면, 클라이언트 컴포넌트는 동적 임포트를 통해 필요한 시점에 로드될 수 있어 초기 로드 시간을 최적화할 수 있습니다.

import { Suspense } from 'react'
import dynamic from 'next/dynamic'
 
const ClientComponent = dynamic(() => import('../components/ClientComponent'), {
  ssr: false, // 클라이언트 사이드에서만 로드
})
 
export default function Page() {
  return (
    <div>
      <ServerComponent />
      <Suspense fallback={<p>Loading client component...</p>}>
        <ClientComponent />
      </Suspense>
    </div>
  )
}

실습 : 대형 차트 라이브러리 동적 임포트

 대형 차트 라이브러리(예 : Chart.js)를 동적으로 임포트하고 로딩 상태를 관리하는 실습을 해보겠습니다.

  1. 먼저, Chart.js를 설치합니다.
npm install chart.js react-chartjs-2
  1. 차트 컴포넌트를 생성합니다.
// components/Chart.js
'use client'
 
import { Line } from 'react-chartjs-2'
import { Chart as ChartJS, CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend } from 'chart.js'
 
ChartJS.register(CategoryScale, LinearScale, PointElement, LineElement, Title, Tooltip, Legend)
 
const data = {
  labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
  datasets: [
    {
      label: 'Sales',
      data: [65, 59, 80, 81, 56, 55, 40],
      fill: false,
      borderColor: 'rgb(75, 192, 192)',
      tension: 0.1
    }
  ]
}
 
export default function Chart() {
  return <Line data={data} />
}
  1. 페이지에서 차트를 동적으로 임포트합니다.
// app/dashboard/page.js
'use client'
 
import { Suspense, useState } from 'react'
import dynamic from 'next/dynamic'
 
const DynamicChart = dynamic(() => import('../../components/Chart'), {
  ssr: false,
  loading: () => <p>Loading chart...</p>
})
 
export default function Dashboard() {
  const [showChart, setShowChart] = useState(false)
 
  return (
    <div>
      <h1>Dashboard</h1>
      <button onClick={() => setShowChart(true)}>Load Chart</button>
      {showChart && (
        <Suspense fallback={<p>Loading chart...</p>}>
          <DynamicChart />
        </Suspense>
      )}
    </div>
  )
}

 이 실습에서는 대형 차트 라이브러리를 동적으로 임포트하고, 사용자가 버튼을 클릭할 때만 로드하도록 구현했습니다. 이를 통해 초기 페이지 로드 시간을 줄이고, 필요한 시점에만 차트 라이브러리를 로드하여 전체적인 애플리케이션 성능을 향상시킬 수 있습니다.

 Next.js의 코드 분할 및 지연 로딩 기능은 대규모 애플리케이션의 성능을 크게 향상시킬 수 있습니다. 자동 코드 분할, 동적 임포트, 그리고 Suspense와의 통합을 통해 개발자는 효율적이고 사용자 친화적인 애플리케이션을 구축할 수 있습니다. 이러한 기술을 적절히 활용하면 초기 로드 시간을 줄이고, 전반적인 사용자 경험을 개선할 수 있습니다.