Post

리액트 코드 분할 (code splitting)

✨코드 분할 (code splitting)

React 공식 문서 - 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 사용 예

dashboardReact

상단 이미지의 어플리케이션은 총 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 요청이 발생할 수도 있음

참고 사이트

This post is licensed under CC BY 4.0 by the author.