리액트 코드 분할 (code splitting)
✨코드 분할 (code splitting)
리액트는 webpack과 같은 번들러을 사용해서, 여러개의 파일을 하나로 병합한 파일을 웹 어플리케이션에 적용을 합니다. 번들은 여러개의 파일을 하나로 병합한다는 장점이 있지만, 파일의 용량이 커지면 번들도 커지기 때문에 처음 화면에 진입할 때 데이터를 다운받는데 오랜 시간 기다려야할 수도 있습니다.
리액트는 번들의 커지는 것을 방지하기 위해 코드 분할(code splitting)을 해결책으로 제시합니다. 코드 분할은 webpack, rollup과 같은 번들러가 기본적으로 제공하는 기능입니다.
📘역할
번들이 커지는 것을 방지하기 위해 코드를 쪼개는 것입니다. 즉, 지금 당장 필요한 코드가 아니라면, 나중에 필요할 때 불러와서 사용하도록 하는 것입니다.
📘사용하는 이유?
코드 분할을 사용하면 필요한 코드만 다운로드하여 초기 로드 시간과 브라우저가 처리해야하는 작업양이 줄어 앱 성능을 개선시킬 수 있습니다.
✨리액트에서 코드 분할하기 with lazy()
, Suspense
리액트에 있는 lazy함수를 사용하면 지연 로딩 시킬 수 있다. lazy로 감싸진 컴포넌트는 Suspense
컴포넌트 하위에서 렌더링되어야한다. Suspense
컴포넌트에는 lazy로 감싸진 컴포넌트가 로드되길 기다리는 동안 보여질 로딩 화면과 같은 콘텐츠를 설정할 수 있습니다.
주로 Route 단계에 적용합니다. 해당 페이지로 접근하기 전까지는 지연로딩 시켜 필요한 컴포넌트들만 다운받아 로드 시간을 줄일 때 사용합니다. 하지만 페이지를 이동할 때 관련 리소스들을 다운받아야하기 때문에 페이지를 이동할 때마다 로딩 화면이 보여지는 단점이 있습니다.
📘lazy 사용하기
lazy 미적용
- 처음 렌더링될 때 OtherComponent를 포함한 번들을 자동으로 불러옴
1
import OtherComponent from "./OtherComponent";
lazy 적용
React.lazy()
로 OtherComponent를 감싸 필요할 때 로드되도록 설정Suspense
의 fallback에 로딩될 때 보여질 화면을 구상
1
2
3
4
5
6
7
8
9
10
11
12
13
import React, { Suspense } from "react";
const OtherComponent = React.lazy(() => import("./OtherComponent"));
function MyComponent() {
return (
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
);
}
📘lazy 사용 예
상단 이미지의 어플리케이션은 총 5개의 페이지로 만들어져있고, 각각의 페이지는 여러개의 위젯들로 이루어져있다. 따라 어플리케이션에 처음 접근할 때에 각 페이지의 데이터들을 모두 로드하기 때문에 인터넷 연결 상태가 좋지 않으면 로드 시간이 오래걸린다.
이럴 때 용량이 큰 페이지들을 lazy
함수로 묶어 지연 로딩을 시켜, 첫 진입시 로드 시간을 줄일 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import React, { lazy, Suspense } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import NotFound from "./pages/NotFound";
const Home = lazy(() => import("./Home"));
const SearchResult = lazy(() => import("./SearchResult"));
const Schedule = lazy(() => import("./Schedule"));
const Todos = lazy(() => import("./Todos"));
const Works = lazy(() => import("./Works"));
const MyPage = lazy(() => import("./MyPage"));
function App() {
return (
<div className="App">
<BrowserRouter>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/search/:query" element={<SearchResult />} />
<Route path="/schedule" element={<Schedule />} />
<Route path="/todos" element={<Todos />} />
<Route path="/works" element={<Works />} />
<Route path="/myPage" element={<MyPage />} />
</Routes>
</Suspense>
<Route path="*" element={<NotFound />} />
</BrowserRouter>
</div>
);
}
export default App;
NotFound
컴포넌트는 지연로딩과는 관련이 없기 때문에 Suspense 밖으로 분리
✨코드분할의 단점
- 코드 분할은 복잡성을 증가시킬 수 있음
- 사용자가 앱을 처음 로드할 때 더 많은 HTTP 요청이 발생할 수도 있음
참고 사이트