리액트를 개발할때는 webpack과 같은 번들링 툴을 이용하여 번들 된 파일을 웹페이지에 포함하여 한번에 전체 앱을 로드하여 개발합니다.
예를 들어 app.js 라는 파일에 math.js 의 함수, 변수들을 import 해서 사용하면 최종적으로 두번째 코드블럭 처럼 하나의 파일에 합쳐지는 것이죠.
// app.js
import { add } from './math.js';
console.log(add(16, 26));
function add(a, b) {
return a + b;
}
console.log(add(16, 26));
실제로는 이렇게 번들링되지 않고, 좀더 압축된 형태, 원하는 ES 문법 버전으로 바꿀 수 있습니다.
규모가 커진다면..
번들링은 여러 파일을 하나로 합쳐주지만, 앱이 커진다면 번들된 파일도 그만큼 커지게 됩니다.
실수로 규모가 엄청나게 큰 서드파티 라이브러리를 추가한다면 앱의 로드시간이 길어지게 되겠죠.
번들이 거대해지는 것을 방지하기 위해서 webpack 과 같은 번들러가 지원하는 "코드 분할"을 사용합니다.
코드 분할은 런타임에 여러 번들을 동적으로 만들고 불러오는 기능입니다.
그러면 사용자가 필요한 페이지에서 필요한 만큼의 코드만 불러와 번들링하기 때문에 필요하지 않은 코드들은 불러오지 않으며 앱의 초기화 로딩에 필요한 비용을 줄일 수 있습니다.
React.lazy
React.lazy 함수를 사용하면 동적 import를 사용해서 컴포넌트를 렌더링 할 수 있습니다.
// before
import lazyComponent from 'lazyComponent';
// after
const lazyComponent = React.lazy(()=> import('./lazyComponent'));
React.lazy(callback);
이 함수는 동적 import()를 호출하는 callback 함수를 인자로 가집니다.
import() 함수는 Promise를 리턴하며(ES11 에 추가된 문법), lazy의 인자로 받는 callback 함수가 그것을 Component의 형태로 변경하고 lazy함수는 컴포넌트를 반환합니다.
Suspense
이렇게 불러온 컴포넌트는 반드시 <Suspense> 컴포넌트의 하위에서 렌더링 되어야 합니다.
또한 Suspense의 props 로 fallback에 컴포넌트를 넣어줄 수 있는데 이는 컴포넌트가 loading 되기 전에 보여줄 예비 컨텐츠입니다.
<div>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent />
</Suspense>
</div>
Suspense의 자식 요소로 여러개의 Lazy 컴포넌트를 감쌀 수 있습니다.
또한 네트워크 장애가 발생했을 경우에 에러바운더리를 통해 사용자에게 알릴 수 있습니다
<div>
<MyErrorBoundary>
<Suspense fallback={<div>Loading...</div>}>
<section>
<OtherComponent />
<AnotherComponent />
</section>
</Suspense>
</MyErrorBoundary>
</div>
페이지별 Lazy 로딩하기
import React, { Suspense } from "react";
import { BrowserRouter, Link, Route, Routes } from "react-router-dom";
const Home = React.lazy(() => import("./components/Home"));
const About = React.lazy(() => import("./components/About"));
function App() {
return (
<>
<BrowserRouter>
<Suspense>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Routes>
</Suspense>
</BrowserRouter>
</>
);
}
export default App;
'Archive' 카테고리의 다른 글
Array-like Object (유사배열) (2) | 2022.07.01 |
---|---|
express 에서 nestJS로 갈아타면서 느낀점 들 (0) | 2022.06.30 |
React 에서 map을 사용할때 Key 값으로 index를 사용하면 안되는 이유 (0) | 2022.06.30 |
LoadBalancer + ACM 사용하기 (0) | 2022.06.30 |
Jest 와 TDD (0) | 2022.06.19 |