[React다루는기술] 25. 코드 스플리팅(Code Splitting)
in React on React 다루는 기술
코드 스플리팅(Code Splitting)은 대규모 웹 애플리케이션을 개발할 때 사용되는 기술로, 애플리케이션의 코드를 여러 개의 작은 조각으로 분할하여 필요한 코드만 사용자에게 제공함으로써 초기 로딩 시간을 줄이고 성능을 향상시키는 방법이다.
1. Code Splitting
전통적으로 웹 애플리케이션은 단일 번들로 제공되었기 때문에, 사용자가 처음 애플리케이션을 로드할 때 모든 코드를 다운로드해야 한다. 이는 초기 로딩 시간을 증가시키고 사용자 경험을 저하시킬 수 있다. 코드 스플리팅은 이러한 문제를 해결하기 위해 애플리케이션을 작은 조각으로 분할하여 필요한 코드만 필요한 시점에 동적으로 로드한다.
동적 임포트(Dynamic import)
: ECMAScript 2015(ES6)에서 도입된 기능으로,import()
함수를 사용하여 모듈을 동적으로 로드할 수 있다. 이를 활용하여 필요한 모듈을 필요한 시점에 로드할 수 있다.Webpack 등의 번들러
: 대표적인 자바스크립트 번들러인 Webpack은 코드 스플리팅을 지원한다. Webpack의 설정을 통해 여러 번들을 생성하고, 애플리케이션 실행 시점에 필요한 번들을 동적으로 로드할 수 있다.React.lazy와 Suspense
: 리액트에서는React.lazy
와Suspense
를 사용하여 컴포넌트 레이지 로딩을 구현할 수 있다. 이를 통해 사용자가 필요한 컴포넌트를 필요한 시점에 로드할 수 있다.Vue Router와 동적 라우팅
: Vue.js에서는 Vue Router를 사용하여 동적 라우팅을 구현할 수 있다. 이를 활용하여 특정 라우트에 필요한 컴포넌트를 필요한 시점에 로드할 수 있다.
이러한 코드 스플리팅 기술을 활용하면 초기 로딩 시간을 줄이고 성능을 향상시킬 수 있으며, 사용자 경험을 향상시킬 수 있다.
2. Code Splitting 예제
$ yarn create react-app splitting-sample
$ yarn build
build 를 한 후에 프로젝트/build/static/ 경로를 보면 해시값 형태로 파일명들이 생성되어있는데 이를 통해 브라우저가 새로 파일을 받아야 할지 말지 알 수 있는 것이다.
SplitChunks 라는 웹팩 기능을 통해 자주 바뀌지 않는 파일들은 main.파일명 이 아닌 숫자로 시작하는 파일들
이고, 코드 수정을 통한 변경 된 파일들은 main.파일명
로 시작하는 파일들이다.
이렇게 SplitChunks 로 파일을 분리하는 것은 코드 스플리팅
이라고 하며, 이렇게 분리해서 SPA어플리케이션에서 페이지가 A부터 Z까지 있다고 할 때 사용자가 접속시에 A~Z 페이지의 모든 컴포넌트와 자바스크립트를 불러오지 않고 사용자가 사용하는 리소스만 사용하는 것이다.
그래서 이러한 문제를 해결해주는게 코드 스플링팅 방법 중 하나인 코드 비동기 로딩
이다. 코드 비동기 로딩을 자바스크립트, 컴포넌트, 객체 등을 필요한 시점에 불러와서 사용하는 개념이다.
2-1. 동적 임포트(Dynamic import) 비동기 로딩
아래와 같이 코드를 작성하고 빌드하면 notify 컴포넌트를 main 파일 안에 들어가게 된다.
import notify from "./notify";
function App() {
const onClick = () => {
notify();
};
return (
<div className="App">
<p>Code SplitChunks 샘플</p>
<p onClick={onClick}>클릭 notify!</p>
</div>
);
}
export default App;
import 를 상단에서 하지 않고 import() 함수 형태로 메서드 안에서 사용하면, 파일을 따로 분리시켜서 저장하고 실제 함수가 필요한 시점에 파일을 불러와서 사용한다.
아래와 같이 import 를 함수로 사용하면 Promise 로 반환하면 동적 임포트(Dynamic import) 문법형태로 작성이 가능하다.
function App() {
const onClick = () => {
import("./notify").then((result) => result.default());
};
return (
<div className="App">
<p>Code SplitChunks 샘플</p>
<p onClick={onClick}>클릭 notify!</p>
</div>
);
}
export default App;
2-2. React.lazy와 Suspense
리액트에서는 내장 함수인 React.lazy
와 컴포넌트인 Suspense
를 사용하여 컴포넌트 레이지 로딩을 구현할 수 있다. 이를 통해 사용자가 필요한 컴포넌트를 필요한 시점에 로드할 수 있다.
React.lazy 는 컴포넌트를 렌더링하는 시점에서 비동기적으로 로딩할 수 있게 해주는 유틸 함수이다.
const SplitMe = React.lazy(() => import('./SplitMe'));
Suspense 는 리액트 내장 컴포넌트로서 코드 스플리팅 된 컴포넌트를 로딩하도록 발동시킬 수 있고
로딩이 끝나지 않았을 때 보여 줄 UI를 설정할 수 있다.
import { Suspense } from "react";
<Suspense fallback={<div>loading...</div>}>
<SplitMe/>
</Suspense>
import React, { useState, Suspense } from "react";
const SplitMe = React.lazy(() => import("./SplitMe"));
function App() {
const [visible, setVisible] = useState(false);
const onClick = () => {
setVisible(true);
};
return (
<div className="App">
<p onClick={onClick}>안녕하세요!!</p>
<Suspense fallback={<div>loading...</div>}>
{visible && <SplitMe />}
</Suspense>
</div>
);
}
export default App;
2-3. Loadable Components
Loadable Components는 리액트 애플리케이션에서 코드 스플리팅을 구현하기 위한 라이브러리 중 하나로 Loadable Components를 사용하면 리액트 컴포넌트를 동적으로 로드하여 번들을 분할할 수 있다.
Loadable Components는 로딩 중에 표시할 커스텀 로딩 컴포넌트 및 로딩 에러 처리를 제공하여 사용자 경험을 향상시키며 서버 사이드 렌더링(SSR) 지원
한다.
$ yarn add @loadable/component
Loadable
함수를 사용하여 컴포넌트 동적 로드할 컴포넌트를 지정한다.
import loadable from "@loadable/component";
// const SplitMe = React.lazy(() => import("./SplitMe"));
const SplitMe = loadable(() => import("./SplitMe"));
function App() {
const [visible, setVisible] = useState(false);
const onClick = () => {
setVisible(true);
};
return (
<div className="App">
<p onClick={onClick}>안녕하세요!!</p>
<Suspense fallback={<div>loading...</div>}>
{visible && <SplitMe />}
</Suspense>
</div>
);
}