대부분의 리액트 앱은 Webpack, Rollup등의 툴을 사용하여 여러 파일을 하나로 병합한 번들된 파일을 우엡 페이지에 포함하여 한 번에 전체 앱을 로드한다.
앱이 커지는 것에 따라 번들도 함께 커진다. 앱의 사이즈가 너무 거대해지면 로드 시간도 길어지는데, 이는 유저 이탈과 같은 행동을 불러온다.
번들 사이즈를 줄이는 좋은 방법으로는 번들을 나누는 것이다.
코드 분할은 런타임에 여러 번들을 동적으로 만들고 불러오는 것으로 이를 통해 앱을 지연 로딩되도록 만들고 사용자에게 획기적인 성능 향상을 제공한다.
앱의 코드 양을 줄이지 않고 당장 필요하지 않은 코드를 불러오지 않도록 하여 초기 로딩에 대한 리소스가 줄어든다.
lazy 함수를 사용하면 동적으로 import하여 컴포넌트를 렌더링할 수 있다.
import React from "react";
import { BrowserRouter, Route, Routes, Navigate } from "react-router-dom";
import { useCookies } from "react-cookie";
import Header from "./components/Header";
import Nav from "./components/Nav";
import Footer from "./components/footer/Footer";
import Main from "./pages/Main";
import Notice from "./pages/Notice";
import KyRecommend from "./pages/KyRecommend";
import Graduate from "./pages/Graduate";
import Mypage from "./pages/Mypage";
import Login from "./pages/Login";
import RouteChangeTracker from "./utils/RouteChangeTracker";
import NoticeDetail from "./pages/NoticeDetail";
import Signup from "./pages/Signup";
import Find from "./pages/Find";
import KyRecommendDetail from "./pages/KyRecommendDetail";
import ModifyInfo from "./pages/ModifyInfo";
function App() {
const [cookies] = useCookies(["accessToken"]);
return (
<BrowserRouter>
<RouteChangeTracker />
<Header />
<Nav />
<Routes>
<Route path="/" element={<Main />} />
<Route path="/notice" element={<Notice />} />
<Route path="/notice/:id" element={<NoticeDetail />} />
<Route path="/KyRecommend" element={<KyRecommend />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
<Route path="/find" element={<Find />} />
<Route
path="/KyRecommend/:id"
element={
cookies.accessToken ? (
<KyRecommendDetail />
) : (
<Navigate replace to="/login" />
)
}
/>
<Route
path="/Graduate"
element={
cookies.accessToken ? (
<Graduate />
) : (
<Navigate replace to="/login" />
)
}
/>
<Route
path="/Mypage"
element={
cookies.accessToken ? <Mypage /> : <Navigate replace to="/login" />
}
/>
<Route
path="/mypage/modifyInfo"
element={
cookies.accessToken ? (
<ModifyInfo />
) : (
<Navigate replace to="/login" />
)
}
/>
</Routes>
<Footer />
</BrowserRouter>
);
}
export default App;
초기에 보이지 않는 리소스 로딩을 기다릴 이유가 없기 때문에 리소스와 사용자 경험의 향상을 위해 Code-splitting기법과 lazy-loading을 사용한다.
import React, { Suspense, lazy } from "react";
import { BrowserRouter, Route, Routes, Navigate } from "react-router-dom";
import { useCookies } from "react-cookie";
import RouteChangeTracker from "./utils/RouteChangeTracker";
import Spinner from "./components/Spinner";
const Header = lazy(() => import("./components/Header"));
const Nav = lazy(() => import("./components/Nav"));
const Footer = lazy(() => import("./components/footer/Footer"));
const Notice = lazy(() => import("./pages/Notice"));
const Main = lazy(() => import("./pages/Main"));
const KyRecommend = lazy(() => import("./pages/KyRecommend"));
const Graduate = lazy(() => import("./pages/Graduate"));
const Mypage = lazy(() => import("./pages/Mypage"));
const Login = lazy(() => import("./pages/Login"));
const NoticeDetail = lazy(() => import("./pages/NoticeDetail"));
const Signup = lazy(() => import("./pages/Signup"));
const Find = lazy(() => import("./pages/Find"));
const KyRecommendDetail = lazy(() => import("./pages/KyRecommendDetail"));
const ModifyInfo = lazy(() => import("./pages/ModifyInfo"));
function App() {
const [cookies] = useCookies(["accessToken"]);
return (
<BrowserRouter>
<RouteChangeTracker />
<Suspense fallback={<Spinner />}>
<Header />
<Nav />
<Routes>
<Route path="/" element={<Main />} />
<Route path="/notice" element={<Notice />} />
<Route path="/notice/:id" element={<NoticeDetail />} />
<Route path="/KyRecommend" element={<KyRecommend />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
<Route path="/find" element={<Find />} />
<Route
path="/KyRecommend/:id"
element={
cookies.accessToken ? (
<KyRecommendDetail />
) : (
<Navigate replace to="/login" />
)
}
/>
<Route
path="/Graduate"
element={
cookies.accessToken ? (
<Graduate />
) : (
<Navigate replace to="/login" />
)
}
/>
<Route
path="/Mypage"
element={
cookies.accessToken ? (
<Mypage />
) : (
<Navigate replace to="/login" />
)
}
/>
<Route
path="/mypage/modifyInfo"
element={
cookies.accessToken ? (
<ModifyInfo />
) : (
<Navigate replace to="/login" />
)
}
/>
</Routes>
<Footer />
</Suspense>
</BrowserRouter>
);
}
export default App;
lazy로 import하여 가져오는 동안 표시할 항목도 지정해야하는데, Suspense를 사용하여 이를 지정한다.
<Suspense fallback={<Spinner />}>
<Route path="/" element={<Main />} />
</Suspense>
너무 과도하게 분리된 코드는 http 요청 수를 증가시키므로 성능 이점이 상쇄될 수 있다.