React
React lazy, Suspense
@kkkk_biiin
2023. 11. 20. 16:48
728x90
React lazy
React 컴포넌트를 동적으로 가져올 수 있는 함수로 dynamic import를 할 수 있게 해 준다. 이는 import()를 통해 불러오는 요소들을 무조건 불러오는 것이 아닌 사용자가 실제로 사용할 때만 로드될 수 있게 해주며, 초기 페이지 로딩 시간을 줄여준다.
Suspense
react lazy 함수를 통해 지연 로딩 된 컴포넌트를 래핑 할 수 있도록 React에서 제공하는 구성 요소로, react lazy를 통해 지연 로딩된 컴포넌트가 로드되는 동안 로드 상태를 처리하고, 대체 콘텐츠를 표시하기 위해 사용된다. 이는 지연 로딩된 컴포넌트가 로드되는 동안 표시할 내용을 지정하는 fallback Props가 필요하며, 기본적으로 로딩 중인 상태를 나타내는 내용을 넣는다.
사용 이유
이러한 기능은코드를 더 작고 관리 가능한 덩어리로 분할하고 필요할 때만 로드할 수 있기 때문에 애플리케이션의 초기 로딩 속도가 크게 향상된다는 점 때문에 사용한다고 볼 수 있다.
프로젝트에서 구현
중고 의류 거래 플랫폼 프로젝트를 진행하면서 React lazy, Suspense를 사용하여 code splitting과 lazy loading을 구현하였고, 그 결과 FCP를 3.5초에서 0.7초로 개선하였다.
중고거래 플랫폼이기 때문에 생각보다 만들어야 할 페이지가 많았고, 각각의 페이지에 적용을 하니 높은 성능 향상을 보여주었다. 실제 프로젝트에서 사용된 코드는 아래와 같다.
import { createBrowserRouter } from 'react-router-dom';
import { lazy, Suspense } from 'react';
import { SyncLoader } from 'react-spinners';
const App = lazy(() => import('./App'));
const Home = lazy(() => import('./pages/Home'));
const Posting = lazy(() => import('./pages/Posting'));
const Mypage = lazy(() => import('./pages/Mypage'));
const Store = lazy(() => import('./pages/Store'));
const ViewItems = lazy(() => import('./pages/ViewItems'));
const Kakao = lazy(() => import('./pages/Redirect'));
const Chat = lazy(() => import('./pages/Chat'));
const Register = lazy(() => import('./pages/Register'));
const Root = lazy(() => import('./pages/Root'));
const Welcome = lazy(() => import('./pages/Welcome'));
const NotFound = lazy(() => import('./pages/NotFound.tsx'));
const router = createBrowserRouter([
{
path: '/',
element: (
<Suspense
fallback={
<div style={{ width: '100%', height: '67.5rem', display: 'flex', justifyContent: 'center', alignItems: 'center' }}>
<SyncLoader color="black" margin={10} size={28} />
</div>
}
>
<App />
</Suspense>
),
children: [
{
path: 'welcome',
element: <Welcome />,
},
{
path: 'kakao',
element: <Kakao />,
},
{
path: '',
element: <Root />,
children: [
{
path: '',
element: <Home />,
},
{
path: 'items/:items/:LargeCategory?/:midCategoryId?/:last?',
element: <ViewItems />,
},
{
path: 'posting/:itemId',
element: <Posting />,
},
{
path: 'mypage',
element: <Mypage />,
},
{
path: 'store/:storeId',
element: <Store />,
},
{
path: 'chat',
element: <Chat />,
},
{
path: 'register/modify?',
element: <Register />,
},
],
},
],
errorElement: <NotFound />,
},
]);
export default router;
728x90