시스템 지식/성능 최적화

[코드 스플리팅] 필요한 코드만 불러오는 기술

Dachaes 2025. 4. 22. 02:31

코드 스플리팅(Code Splitting) 

애플리케이션이 커질수록 번들 파일 크기가 커지고, 이로 인해 페이지 초기 로딩 속도가 느려집니다. 사용자는 빈 화면을 오래 기다려야 하고, 모바일 환경에서는 데이터 사용량까지 증가하죠. 이 문제를 해결하는 대표적인 기술이 바로 코드 스플리팅(Code Splitting)입니다.

코드 스플리팅은 하나의 큰 자바스크립트 번들을 여러 개의 작은 청크(chunk)로 분할하여, 필요한 순간에만 불러오도록 하는 최적화 기법입니다.

 


1.  코드 스플리팅이란?

코드 스플리팅(Code Splitting)은 웹 애플리케이션의 코드를 기능 단위 또는 페이지 단위로 분리하여, 필요한 시점에만 각 코드 블록을 로드하도록 만드는 기술입니다.

왜 필요한가요?

  • 초기 로딩 시간 단축
  • 렌더링 속도 개선
  • 불필요한 자바스크립트 실행 방지
  • 모바일 네트워크 환경 대응

코드 스플리팅의 종류

  1. 라우트 기반 스플리팅 : 페이지 단위로 분리 (Next.js 등에서 기본 제공)
  2. 컴포넌트 기반 스플리팅 : 무거운 UI 컴포넌트를 동적으로 로드
  3. 라이브러리 스플리팅 : 특정 시점에만 필요한 외부 라이브러리를 분리하여 로드

코드 스플리팅 적용 시 주의사항

  • 스플리팅이 너무 과하면 네트워크 요청이 많아져 성능이 떨어질 수 있습니다.
  • 자주 사용하는 공통 컴포넌트는 오히려 번들에 포함하는 것이 유리합니다.
  • fallback UI를 적절히 구성해야 사용자 경험을 해치지 않습니다.

 


2.  코드 스플리팅 예제

a.  Vue.js에서의 코드 스플리팅

Vue는 라우트 기반 또는 컴포넌트 단위로 코드 스플리팅을 지원합니다.

 

i.  라우트 기반 스플리팅 (Vue Router)

const routes = [
  {
    path: '/about',
    component: () => import('../views/AboutView.vue'), // Lazy-load
  },
];
  • 해당 라우트가 방문될 때만 AboutView.vue가 로드됩니다.

ii.  컴포넌트 지연 로딩

import { defineAsyncComponent } from 'vue';

const HeavyChart = defineAsyncComponent(() =>
  import('./components/HeavyChart.vue')
);
  • defineAsyncComponent 를 사용하면 컴포넌트를 필요할 때만 로드할 수 있습니다.

b.  React에서의 코드 스플리팅 - React.lazy + Suspense

React는 내장된 React.lazy Suspense 를 통해 코드 스플리팅을 손쉽게 지원합니다.

 

i.  무거운 컴포넌트를 지연 로딩하기

import { lazy, Suspense } from 'react';

// 컴포넌트 동적 import
const Chart = lazy(() => import('./HeavyChart'));

export default function Dashboard() {
  return (
    <div>
      <h1>대시보드</h1>
      <Suspense fallback={<div>차트를 불러오는 중...</div>}>
        <Chart />
      </Suspense>
    </div>
  );
}
 
  • React.lazy() 를 사용하면 컴포넌트를 동적으로 로드합니다.
  • Suspense 는 로딩 중 보여줄 fallback UI를 설정합니다.
  • 실제로는 Webpack이 컴포넌트를 별도 청크로 분리하여 필요한 시점에만 로드합니다.

c.  Next.js에서의 코드 스플리팅

Next.js는 페이지 기반의 자동 코드 스플리팅을 지원합니다. 각 pages 폴더의 파일은 별개의 번들로 처리되어, 해당 페이지를 방문할 때만 로딩됩니다.

 

i.  페이지 기반 스플리팅

pages/
├── index.js        # / → 메인 페이지
├── about.js        # /about → 이 페이지는 접근 시에만 로드됨
  • Next.js는 이 구조를 기반으로 라우팅 단위의 청크 분리를 자동으로 처리합니다.

ii.  커스텀 컴포넌트 지연 로딩 (Next.js 전용 next/dynamic)

Next.js는 next/dynamic 을 통해 컴포넌트 단위 코드 스플리팅도 제공합니다.

import dynamic from 'next/dynamic';

// 동적 로딩 컴포넌트 정의
const DynamicComponent = dynamic(() => import('../components/HeavyComponent'), {
  loading: () => <p>로딩 중...</p>,
  ssr: false, // 필요 시 서버 사이드 렌더링 비활성화
});

export default function Page() {
  return (
    <div>
      <h1>동적 컴포넌트</h1>
      <DynamicComponent />
    </div>
  );
}
  • dynamic() 으로 import하면 해당 컴포넌트는 초기 번들에서 제외됩니다.
  • 필요 시점(페이지 렌더링 시)에만 별도의 청크로 로드됩니다.
  • ssr: false 를 통해 서버 렌더링에서 제외할 수 있습니다.

 


3.  마무리

  • 코드 스플리팅은 자바스크립트 번들을 필요한 시점에만 로드하도록 나누는 최적화 기술입니다.
  • React에서는 React.lazySuspense, Next.js에서는 next/dynamic으로 구현할 수 있습니다.
  • 자동 라우트 기반 스플리팅을 활용하면 성능을 극대화할 수 있습니다.
  • 초기 로딩을 빠르게 하고, 사용자 경험을 향상시키며, 모바일 환경에도 유리한 기술입니다.

함께 하면 좋은 자료

외부 사이트 :