번들링은 훌륭하지만 앱이 커지면 번들도 커져서 로드 속도가 느려집니다. 프로젝트 초기라면 괜찮습니다. 하지만 프로젝트 규모가 커지고 최적화가 필요한 단계에서 Code Splitting을 한다면 서비스 퍼포먼스가 좋아지기 때문에 사용자들에게 보다 나은 사용자 경험을 줄 수 있습니다.
방법 #1. React.lazy
React.lazy 함수를 사용하면 동적 import를 사용해서 컴포넌트를 렌더링 할 수 있습니다.
(React.lazy는 React 16.6버전 부터 지원합니다.)
import 하는 페이지 내부에 사용중인 컴포넌트가 사용하지 않는 다른 컴포넌트와 index.js에 export를 편의상 묶어 사용하는 경우가 있습니다. 이때 컴포넌트 import시 객체 디스트럭쳐링을 사용할 경우 내부적으로 사용하지 않는 컴포넌트도 함께 로드되기 때문에 코드 분할 시 큰 효과를 보지 못합니다. 그렇기 때문에 실사용 컴포넌트만 개별 임포트 하는것이 중요합니다.
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 예로, PageA를 코드 분할하려고 합니다.
const PageA = React.lazy(()=>import("./PageA"));
functionMyComponent(){
return(
<div>
<Suspense fallback={<div>Loading...</div>}>
<PageA/>
</Suspense>
</div>
);
}
// PageA.js 에선 Button 컴포넌트를 사용하려고 import하고 있습니다.
// X 사용하지 않는 다른 컴포넌트도 함께 로드됩니다.
import{ Button } from "./components";
// O 개별 컴포넌트로 로드해야 불필요한 컴포넌트가 불려 번들 사이즈가 커지는것을 방지할 수 있어요.
import Button from "./components/Button";
functionPageA(){
return(
<div>
<h1>PageA</h1>
<Button>OK</Button>
</div>
);
}
// components/index.js
export{defaultas Loader } from "./common/Loader";
export{defaultas Button } from "./common/OtherSetting";
export{defaultas InsideSearch } from "./common/InsideSearch";
// 예로, PageA를 코드 분할하려고 합니다.
const PageA = React.lazy(() => import("./PageA"));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<PageA />
</Suspense>
</div>
);
}
// PageA.js 에선 Button 컴포넌트를 사용하려고 import하고 있습니다.
// X 사용하지 않는 다른 컴포넌트도 함께 로드됩니다.
import { Button } from "./components";
// O 개별 컴포넌트로 로드해야 불필요한 컴포넌트가 불려 번들 사이즈가 커지는것을 방지할 수 있어요.
import Button from "./components/Button";
function PageA() {
return (
<div>
<h1>PageA</h1>
<Button>OK</Button>
</div>
);
}
// components/index.js
export { default as Loader } from "./common/Loader";
export { default as Button } from "./common/OtherSetting";
export { default as InsideSearch } from "./common/InsideSearch";
// 예로, PageA를 코드 분할하려고 합니다.
const PageA = React.lazy(() => import("./PageA"));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<PageA />
</Suspense>
</div>
);
}
// PageA.js 에선 Button 컴포넌트를 사용하려고 import하고 있습니다.
// X 사용하지 않는 다른 컴포넌트도 함께 로드됩니다.
import { Button } from "./components";
// O 개별 컴포넌트로 로드해야 불필요한 컴포넌트가 불려 번들 사이즈가 커지는것을 방지할 수 있어요.
import Button from "./components/Button";
function PageA() {
return (
<div>
<h1>PageA</h1>
<Button>OK</Button>
</div>
);
}
// components/index.js
export { default as Loader } from "./common/Loader";
export { default as Button } from "./common/OtherSetting";
export { default as InsideSearch } from "./common/InsideSearch";
방법 #2. Loadable Components
React.lazy와 Suspense는 서버 사이드 렌더링을 지원하지 않습니다. 코드 분할을 클라이언트, 서버사이드 모두 가능하도록 만들고 싶다면 Loadable Components를 사용하면됩니다. (React 공식 문서에서 권장하는 방법)
React.lazy와 비교
Library
Suspense
SSR
Library splitting
import(./${value})
React.lazy
@loadable/component
Install
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install @loadable/component
# or use yarn
yarn add @loadable/component
npm install @loadable/component
# or use yarn
yarn add @loadable/component
npm install @loadable/component
# or use yarn
yarn add @loadable/component
React-loadable 모듈은 React 공식 문서에서도 오랫동안 권장하던 방법이었습니다. 그러나 현재는 더 이상 유지 관리되지 않으며 Webpack v4 + 및 Babel v7 +와 호환되지 않는 부분들이 있습니다.
그래서 React.lazy 또는 Loadable components로 변경하는것을 추천합니다.