애플리케이션이 커질수록 성능 저하의 가장 큰 원인은?
바로 무분별하게 커진 번들 파일입니다.
300kb 이상 JS를 한번에 로딩하고 있다면
,
지금이 바로 코드 스플리팅을 도입할 시점입니다.
코드 스플리팅이란?
Code Splitting은 애플리케이션의 JavaScript 코드를 여러 개의 청크(파일)로 분리해서 로딩하는 기술입니다.
모든 코드를 하나의 파일에 모아서 한 번에 불러오는 대신,
필요한 코드만 분리해서 나중에 비동기적으로 불러올 수 있게 합니다.
꼭 필요한 코드만 먼저 불러오고, 나머지는 나중에!
왜 코드 스플리팅이 필요한가?
SPA에서 모든 컴포넌트를 하나의 main.js
에 포함하면
- 초기 로딩 시간이 너무 길어짐
- 사용하지도 않는 코드가 로딩되어 낭비 발생
- 사용자 이탈률 증가
코드 스플리팅은 번들 크기를 줄여 초기 성능을 향상시키는 매우 중요한 전략입니다.
코드 스플리팅 vs Lazy Loading
많은 분이 코드 스플리팅과 Lazy Loading을 같은 개념으로 보지만, 사실 이 둘은 조금 다릅니다.
구분 | 코드 스플리팅 | Lazy Loading |
정의 | 코드 번들을 작게 쪼갬 | 특정 시점에 필요한 리소스를 불러옴 |
목적 | 번들 최적화 | 사용자 경험 개선 |
관계 | 코드 스플리팅이 Lazy Loading의 기반 기술 | 코드 스플리팅 위에 구현되는 UX 전략 |
즉, Lazy Loading은 코드 스플리팅을 활용한 UI 최적화 기법이라고 볼 수 있습니다.
코드 스플리팅의 동작 원리
- 빌드 시 Webpack이 코드를 분석하여 의존성에 따라 여러 청크로 나눕니다.
- 애플리케이션 실행 시 필요한 청크만 먼저 로딩됩니다.
- 사용자의 인터랙션에 따라 나머지 청크가 동적으로 요청되어 로딩됩니다.
React, Vue, Angular 같은 프레임워크는 Webpack, Vite 같은 번들러를 통해 코드 스플리팅을 자동 처리합니다.
코드 스플리팅을 적용하는 방법 (React)
1) React.lazy()
와 Suspense
사용
import React, { Suspense, lazy } from 'react';
const Chart = lazy(() => import('./components/HeavyChart'));
function App() {
return (
<Suspense fallback={<div>로딩 중...</div>}>
<Chart />
</Suspense>
);
}
lazy()
는 청크를 분리하고, 나중에 import하게 해줍니다.Suspense
는 로딩 상태를 관리합니다.
이렇게 하면
HeavyChart
는 초기에 번들에 포함되지 않고, 해당 컴포넌트가 렌더링될 때 다운로드됩니다.
2) 라우트 단위 코드 스플리팅 (React Router v6)
import { lazy, Suspense } from 'react';
import { createBrowserRouter } from 'react-router-dom';
const SettingsPage = lazy(() => import('./pages/Settings'));
const router = createBrowserRouter([
{
path: '/settings',
element: (
<Suspense fallback={<div>페이지 로딩 중...</div>}>
<SettingsPage />
</Suspense>
)
}
]);
페이지 단위 코드 분리는 가장 흔한 패턴입니다.
3) Webpack에서 자동 코드 스플리팅
Webpack의 dynamic import 기능은 빌드 시 코드를 자동으로 분리해줍니다.
// 동적 import
import('./moduleA').then((module) => {
module.doSomething();
});
위와 같은 코드는 moduleA
를 별도의 청크로 분리합니다.
React가 아닌 환경에서도 Webpack, Vite 등에서 활용 가능합니다.
코드 스플리팅의 장점
장점 | 설명 |
초기 로딩 속도 개선 | 필수 코드만 먼저 로딩 |
UX 향상 | 사용자가 빠르게 컨텐츠를 볼 수 있음 |
트래픽 절약 | 사용자가 방문하지 않는 페이지는 다운로드되지 않음 |
유지보수 용이 | 기능별 코드 분리로 구조가 명확해짐 |
확장성 증가 | 앱이 커져도 성능 저하를 최소화 가능 |
코드 스플리팅의 주의점 및 단점
단점 | 설명 |
초기 구현 복잡성 | Suspense, Lazy, Route 구성 등 설정 필요 |
Fallback UI 필수 | 로딩 중 상태를 잘 보여주지 않으면 UX 저하 |
청크가 너무 작아지면 역효과 | 네트워크 요청이 과다하게 발생할 수 있음 |
캐싱 관리 필요 | 동적으로 로딩된 JS 청크 캐싱 정책 설정 필요 |
정리
코드 스플리팅은 더 이상 선택이 아닌 필수입니다.
앱이 커질수록, 페이지가 많아질수록, 기능이 복잡해질수록 초기 번들을 줄이는 것은 매우 중요해지죠.
React, Webpack, Vite 등 현대 프론트엔드 생태계에서는 코드 스플리팅을 위한 다양한 방법이 지원되므로,
초기 로딩 시간 줄이기 → 사용자 경험 개선 → 유지보수 효율 상승이라는 선순환 구조를 만들 수 있습니다.