[React] React lazy로 웹 성능 최적화 하기 (코드 스플리팅)
최근에 리액트로 프로젝트를 하면서 한 번에 여러 컴포넌트들을 불러오게 되면서
웹 성능이 떨어지는 일이 있었습니다.
이에 React.lazy를 통한 코드 스플리팅으로 성능을 개선해보고자 했습니다.
| 코드 스플리팅
리액트에서 개발을 하고 배포할 때 빌드를 하게 되는데 이때 보통 단일 Javascript 파일로 번들링 하게 됩니다.
이 방식은 애플리케이션의 크기가 커지면 초기 로딩 시간이 길어지는 문제를 야기할 수 있어서 코드 스플리팅을 통해 전체 번들을 더 작은 크기로 나누고, 이를 비동기적으로 로드할 수 있게 함으로써 로딩 시간을 개선하게 해주는 것을 코드 스플리팅이라 합니다.
| React lazy
리액트의 lazy와 Suspense로 필요할 때에 컴포넌트를 로드할 수 있도록 하려면
아래와 같이 코드를 작성하면 됩니다.
import { lazy, Suspense } from 'react';
const Component2 = lazy(() => import('./Component2'));
const Component1 = () => {
return (
<div>
<Suspense fallback={<div>로딩</div>}>
<Component2 />
</Suspense>
</div>
);
}
여기서 Component2는 Component1이 화면에 렌더링 될 때까지 로딩이 시작되지 않습니다.
이런 식으로 사용자가 실제로 Component2를 볼 필요가 있을 때까지 해당 컴포넌트로의 로드를 미룰 수 있습니다.
여기서 Suspense는 리액트가 컴포넌트의 로드를 기다리는 동안 보여줄 대체 UI를 정의할 수 있도록 해줍니다.
| 적용
제가 작업하던 프로젝트에 react router와 함께 적용해 보겠습니다.
main.tsx파일에서 아래와 같이 여러 컴포넌트를 한 번에 불러와 react router를 적용하고 있습니다.
import Cart from "./pages/Cart";
import Main from "./pages/Main";
import Category from "./pages/Category";
...생략
const router = createBrowserRouter([
{
path: "/",
element: <Main />,
},
{
path: "/cart",
element: <Cart />,
},
{
path: "/category",
element: <Category />,
},
...생략
]);
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<RouterProvider router={router} />
</React.StrictMode>
);
이런 식으로 되면 처음에 페이지에 진입 시 모든 페이지에 대한 정보를 불러오면서 초기 로딩을 느리게 만들 수 있습니다.
이때 리액트의 lazy를 사용하면 컴포넌트를 지연 로딩해서 필요한 스크립트를 그때그때 불러오도록 할 수 있습니다.
const Cart = lazy(() => import("./pages/Cart"));
const Main = lazy(() => import("./pages/Main"));
const Complete = lazy(() => import("./pages/Complete"));
...생략
const router = createBrowserRouter([
{
path: "/",
element: <Main />,
},
{
path: "/cart",
element: <Cart />,
},
{
path: "/category",
element: <Category />,
},
...생략
]);
ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<Suspense fallback={<div>로딩</div>}>
<RouterProvider router={router} />
</Suspense>
</React.StrictMode>
);