ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] React lazy로 웹 성능 최적화 하기 (코드 스플리팅)
    React 2024. 2. 12. 00:28

    최근에 리액트로 프로젝트를 하면서 한 번에 여러 컴포넌트들을 불러오게 되면서
    웹 성능이 떨어지는 일이 있었습니다.

    이에 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>
    );
Designed by Tistory.