[React] 배포 (Lazy Loading)

정호·2024년 4월 5일
0

TIL

목록 보기
15/15

Lazy Loading

페이지나 컴포넌트를 필요한 시점에만 불러오는 기술
초기 페이지 로딩 시 모든 자원을 미리 로드하는 것이 아니라, 사용자가 해당 자원을 필요로 할 때 비동기적으로 로드하여 성능을 향상시키고 초기 로딩 시간을 단축하는 데 도움된다.

--> 모든 페이지를 한번에 불러오는 것은 효율적이지 않기때문에 필요한 자원만 불러오는 방식

구현 방법

  • 코드 분할(Code Splitting)
    애플리케이션을 여러 번의 요청으로 분할하여 필요한 부분만 요청할 수 있다. 주로 Webpack, Parcel 등의 번들러를 사용하여 코드를 자동으로 분할한다.

  • 동적 임포트(Dynamic Import)
    ES6의 import() 함수를 사용하여 모듈을 동적으로 불러온다. 이를 통해 필요한 시점에만 모듈을 불러올 수 있다.

  • 컴포넌트 수준의 Lazy Loading
    React와 Vue.js 같은 프레임워크에서는 컴포넌트를 비동기적으로 로드할 수 있는 기능을 제공한다. 이를 통해 페이지에 필요한 컴포넌트만 로드하여 초기 로딩 시간을 최적화할 수 있다.


코드 구현

1. loader 동적 처리

예시) 웹사이트를 렌더링할때 blog컴포넌트를 먼저 로딩할 필요 없으므로 import처리

이전코드

import { createBrowserRouter, RouterProvider } from 'react-router-dom';

import BlogPage, { loader as postsLoader } from './pages/Blog';
import HomePage from './pages/Home';
import PostPage, { loader as postLoader } from './pages/Post';
import RootLayout from './pages/Root';


const router = createBrowserRouter([
  {
    path: '/',
    element: <RootLayout />,
    children: [
      {
        index: true,
        element: <HomePage />,
      },
      {
        path: 'posts',
        children: [
          { index: true, element: <BlogPage />, loader: postsLoader },
          { path: ':id', element: <PostPage />, loader: postLoader },
        ],
      },
    ],
  },
]);

function App() {
  return <RouterProvider router={router} />;
}

export default App;

리팩토링

import { createBrowserRouter, RouterProvider } from "react-router-dom";

// import BlogPage, { loader as postsLoader } from './pages/Blog';
import HomePage from "./pages/Home";
import PostPage, { loader as postLoader } from "./pages/Post";
import RootLayout from "./pages/Root";

const router = createBrowserRouter([
  {
    path: "/",
    element: <RootLayout />,
    children: [
      {
        index: true,
        element: <HomePage />,
      },
      {
        path: "posts",
        children: [
          {
            index: true,
            element: <BlogPage />,
            loader: () =>
              import("./pages/Blog").then((module) => module.loader()),
          },
          { path: ":id", element: <PostPage />, loader: postLoader },
        ],
      },
    ],
  },
]);

function App() {
  return <RouterProvider router={router} />;
}

export default App;
  1. import주석처리
  2. loader 동적으로 import처리
  3. 블로그 페이지를 방문해야만 블록 파일이 import되고 파일이 loader됨

2. 컴포넌트 지연 로딩적용

suspense

리액트에서 제공하는 컴포넌트로 실제 콘텐츠를 렌더링 하기전에 로딩을 기다리는데 사용
코드 불러오기 전에 fallback 보여줌

  path: "posts",
        children: [
          {
            index: true,
            element: (
              <Suspense fallback={<p>Loading...</p>}>
                <BlogPage />
              </Suspense>
            ),
            loader: () =>
              import("./pages/Blog").then((module) => module.loader()),
          },

lazy

Lazy Loading
lazy 함수를 사용하여 동적으로 컴포넌트를 불러 각 컴포넌트는 필요한 시점에만 로드

const BlogPage = lazy(() => import("./pages/Blog"));
const PostPage = lazy(() => import("./pages/Post"));

완성코드

import { lazy, Suspense } from "react";
import { createBrowserRouter, RouterProvider } from "react-router-dom";

// import BlogPage, { loader as postsLoader } from './pages/Blog';
import HomePage from "./pages/Home";
// import PostPage, { loader as postLoader } from './pages/Post';
import RootLayout from "./pages/Root";

const BlogPage = lazy(() => import("./pages/Blog"));
const PostPage = lazy(() => import("./pages/Post"));

const router = createBrowserRouter([
  {
    path: "/",
    element: <RootLayout />,
    children: [
      {
        index: true,
        element: <HomePage />,
      },
      {
        path: "posts",
        children: [
          {
            index: true,
            element: (
              <Suspense fallback={<p>Loading...</p>}>
                <BlogPage />
              </Suspense>
            ),
            loader: () =>
              import("./pages/Blog").then((module) => module.loader()),
          },
          {
            path: ":id",
            element: (
              <Suspense fallback={<p>Loading...</p>}>
                <PostPage />
              </Suspense>
            ),
            loader: (meta) =>
              import("./pages/Post").then((module) => module.loader(meta)),
          },
        ],
      },
    ],
  },
]);

function App() {
  return <RouterProvider router={router} />;
}

export default App;
profile
열심히 기록할 예정🙃

0개의 댓글