런타임에 여러 번들을 동적으로 만들고 불러오는 것으로 Webpack, Rollup과 Browserify 같은 번들러가 지원하는 기능이다.
코드 분할은 앱을 지연 로딩하게 도와주기 때문에 사용자는 향상된 성능을 경험할 수 있다. 사용자에게 필요하지 않은 코드는 불러오지 않고, 앱의 초기 로딩에 필요한 비용을 줄여준다.
React.lazy와 Suspense는 아직 서버 사이드 렌더링(SSR)을 할 수 없다.
React.lazy
는 동적으로 컴포넌트를 불러올 수 있게 해주는 함수이다. (컴포넌트를 렌더링하는 시점에서 비동기적으로 로딩할 수 있게 해줌)
lazy 함수의 인자로 동적인 import를 하는 함수를 넣어주면 된다.
import OtherComponent from './OtherComponent';
// SomeComponent를 동적으로 불러옴.
const OtherComponent = React.lazy(() => import('./OtherComponent'));
// MyComponent.js
export default MyComponent;
// MyApp.js
import React, { lazy } from 'react';
const MyComponent = lazy(() => import("./MyComponent.js"));
Suspense
는 트리 상에 아직 렌더링이 준비되지 않은 컴포넌트가 있을 때 로딩 중임을 나타내주는 컴포넌트이다.
lazy 컴포넌트는 Suspense 컴포넌트 하위에 위치해야한다.
import React, { Suspense } from 'react';
const OtherComponent = React.lazy(() => import('./OtherComponent'));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
코드를 어떻게 분할해야 할지 모르겠을 때는 보통 라우팅을 기준으로 하는 것이 좋다. 아래 코드는 react router를 이용해서 코드 분할을 했다.
import React, { Suspense, lazy } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
const Home = lazy(() => import('./routes/Home'));
const About = lazy(() => import('./routes/About'));
const App = () => (
<Router>
<Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
</Switch>
</Suspense>
</Router>
);
우선 코드 분할을 하지 않았고 한번에 렌더링을 했다. main.chunk.js에 모든 Bye, Middle 컴포넌트 코드가 담겨있다.
이번에는 Bye 컴포넌트와 Middle 컴포넌트를 분할시켰다. 코드 분할을 하지 않았을 떄는 main.chunk.js만 존재했지만 이번에는 1.chunk.js
와 2.chunk.js
파일이 생긴 것을 알 수 있다.
1.chunk.js
에는 Bye 컴포넌트, 2.chunk.js
에는 Middle 컴포넌트 코드가 있는 것을 알 수 있다.