FrontEnd/React

[React] lazy()와 Suspense를 활용한 동적 로딩 및 로딩 페이지 구현

devOhzl 2025. 2. 4. 12:30

React에서 페이지 또는 컴포넌트를 동적 로딩할 때, React.lazy()와 Suspense를 사용하면 효율적으로 관리할 수 있습니다.

 

lazy()를 활용한 동적 로딩(Route 정리)

기본적으로 React에서는 import를 사용하여 정적인 방식으로 컴포넌트를 불러옵니다.
하지만, 페이지가 많아질수록 초기 로딩 속도가 느려지는 문제가 발생합니다.

👉 이를 해결하기 위해 React.lazy()를 사용하면, 필요한 순간에만 컴포넌트를 불러올 수 있습니다.


이 방식은 코드 스플리팅(Code Splitting)을 적용하여 성능 최적화에도 도움을 줍니다.

 

정적 로딩 방식 (비효율적인 예시)

이 방식은 모든 페이지가 초기 로딩 시점에 한 번에 불러와지기 때문에 초기 로딩 속도가 느려질 수 있다.

import Home from "@/pages/Home";
import About from "@/pages/About";
import Contact from "@/pages/Contact";

const routes = [
  { path: "/", element: <Home /> },
  { path: "/about", element: <About /> },
  { path: "/contact", element: <Contact /> },
];

 

lazy()를 사용한 동적 로딩 방식 (권장)

lazy()를 사용하면 해당 페이지가 필요한 순간에만 로드되어 초기 렌더링 속도가 개선됩니다.

import { lazy } from "react";

const Home = lazy(() => import("@/pages/Home"));
const About = lazy(() => import("@/pages/About"));
const Contact = lazy(() => import("@/pages/Contact"));

const routes = [
  { path: "/", element: <Home /> },
  { path: "/about", element: <About /> },
  { path: "/contact", element: <Contact /> },
];

 

Suspense를 활용하여 로딩 화면 추가

lazy()로 불러오는 컴포넌트는 비동기적으로 로드되기 때문에, 아직 로드되지 않은 상태에서 화면이 비어있을 수 있습니다.
이를 해결하려면 Suspense를 사용하여 로딩 화면을 추가해야 합니다.

👉 Suspense를 활용하면, 컴포넌트가 로딩될 때 로딩 UI (ex: 스피너, 진행 바 등)를 표시할 수 있습니다.

 

기본적인 Suspense 적용

import { lazy, Suspense } from "react";

const Home = lazy(() => import("@/pages/Home"));
const About = lazy(() => import("@/pages/About"));
const Contact = lazy(() => import("@/pages/Contact"));

const App = () => {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
      </Routes>
    </Suspense>
  );
};

export default App;

 

LinearProgress를 활용한 로딩 UI 만들기

페이지가 로드될 때 LinearProgressBar가 상단에 표시되며 로딩이 완료되면 자동으로 사라지는 효과를 줄 수 있습니다.

import { LinearProgress, Box } from "@mui/material";

const LinearProgressBar = () => {
  return (
    <Box sx={{ width: "100%" }}>
      <LinearProgress />
    </Box>
  );
};

export default LinearProgressBar;
import { lazy, Suspense } from "react";
import { Routes, Route, BrowserRouter as Router } from "react-router-dom";
import LinearProgressBar from "@/components/ui/LinearProgressBar"; // 로딩 컴포넌트

const Home = lazy(() => import("@/pages/Home"));
const About = lazy(() => import("@/pages/About"));
const Contact = lazy(() => import("@/pages/Contact"));

const App = () => {
  return (
    <Router>
      <Suspense fallback={<LinearProgressBar />}>
        <Routes>
          <Route path="/" element={<Home />} />
          <Route path="/about" element={<About />} />
          <Route path="/contact" element={<Contact />} />
        </Routes>
      </Suspense>
    </Router>
  );
};

export default App;

 

lazy() + Suspense + LinearProgress로 최적화하는 장점

  • 초기 로딩 속도 최적화 → lazy()를 사용하면, 처음부터 모든 페이지를 로드하지 않아도 됨
  • 부드러운 사용자 경험 → Suspense를 활용하여 로딩 중에도 사용자에게 시각적인 피드백 제공
  • MUI LinearProgress 적용 → 단순한 "Loading..." 대신 깔끔한 진행 바를 제공하여 UX 개선