카테고리 없음

[Next.js] Lazy Loading & Suspense 성능 최적화

프론트엔드코린이 2025. 2. 10. 00:35

1. Lazy Loading & Suspense란 무엇일까?

레이지 로딩(Lazy Loading)과 서스펜스(Suspense)는 성능 최적화를 위한 기법으로, 리소스를 효율적으로 로드하여 사용자 경험을 향상시키는 역학을 한다.

  • Lazy Loading (지연 로딩): 필요한 시점에만 리소스를 로드하여 초기 로딩 속도를 개선하는 방법
  • Suspense: 로딩 중인 컴포넌트를 감싸서 대체 UI(로딩 화면 등)를 제공하는 기능


설명을 봐도 모르겠는데...?

※ 이론만 보고 이해가 가지 않을테니 예시를 들어줄게!

1. Lazy Loading의 예시

import HomePage from "./HomePage";
import AboutPage from "./AboutPage";

function App() {
  return (
    <div>
      <HomePage />
      <AboutPage />
    </div>
  );
}
  • 위 코드의 예시는 우리가 일반적으로 import를 활용하여 HomePage, AboutPage 위 2개의 페이지를 동시에 불러온 후 2개의 페이지를 렌더링 하는 일반적인 코드 예시야! 위 코드는 어렵지 않지...?

👀 기본 import의 특징

  • 정적 import 사용 (import HomePage from "./HomePage";)
  • 앱이 실행될 때 HomePage, AboutPage가 한 번에 로드됨
  • 초기 로딩 속도가 느려질 수 있음 (필요 없는 컴포넌트도 미리 불러오기 때문)

🔥 장점

즉시 렌더링 가능 → 네트워크 요청 없이 바로 컴포넌트를 렌더링
간단한 코드 → Suspense가 필요 없고, 로딩 상태를 따로 처리할 필요 없음

😡 단점

초기 로딩 속도 저하 → 모든 페이지를 한 번에 로드하므로 앱 시작이 느려질 수 있음
불필요한 리소스 로딩 → 사용하지 않는 컴포넌트까지 미리 불러오므로 네트워크 낭비


  • ※ 자! 그럼 lazy loading이 도대체 뭔데....? 바로 알려줄게!
import React, { Suspense, lazy } from "react";
import AboutPage from "./AboutPage"

const HomePage = lazy(() => import("./HomePage"));

function App() {
  return (
    <div>
      <Suspense fallback={<div>Loading...</div>}>
        <HomePage />
      </Suspense>
      <AboutPage />
    </div>
  );
  • 위 코드를 살표보면 import 구문이 뭔가 다르지??
    1. lazy() 메서드를 사용하면 불러올 컴포넌트를 동적으로 import하여, 필요한 순간에만 로드할 수 있어!
      • const 컴포넌트 이름 = lazy() + import('가져올 파일의 위치')
        • 결론은... 문법이라고 생각하고 그냥 외우자...ㅠㅠ!
    2. lazy()는 동적으로 컴포넌트를 불러오므로, React는 로드되는 동안 UI를 어떻게 처리해야 할지 알아야 해 !
      • 따라서 Suspense를 반드시 함께 사용해야 하고, 보통 fallback을 이용해 로딩 중임을 표시하는 UI를 제공해!

👀 lazy import의 특징

  • React.lazy() + import()를 사용하여 레이지 로딩 적용
  • Suspense fallback={
    Loading...
    }을 사용하여 로딩 중 UI 표시
  • HomePage는 앱이 처음 로드될 때 가져오지 않음!
  • 사용자가 해당 컴포넌트를 보려 할 때 네트워크에서 가져옴

🔥 장점

초기 로딩 속도 향상 → 첫 화면에서 필요하지 않은 컴포넌트는 불러오지 않음
번들 크기 감소 → 필요한 컴포넌트만 로드해서 네트워크 트래픽 최적화
최적화된 성능 → 사용자가 페이지를 탐색할 때 비로소 로드

😡 단점

첫 로딩 시 지연 발생 → 컴포넌트를 불러올 때 네트워크 요청이 필요하므로 약간의 딜레이가 생길 수 있음
Suspense 필수 → Lazy Loading을 사용할 때 반드시 로 감싸야 함

※ 요약하자면

  1. lazy()로 불러온 컴포넌트는 비동기적으로 동작

  2. React는 비동기 렌더링을 직접 처리할 수 없으므로, Suspense를 사용해야 함

    • Suspense 없이 실행하면?

        Error: A component was suspended while responding to synchronous input.
        This will cause the UI to be replaced with a fallback.
      • 위 에러 원인은 간단히 서스펜스를 사용하는 동안에 문법 에러가 발생했는데 원인은 대체할 UI가 없다는거야
  3. 일반적으로 "Loading..." 같은 메시지를 표시하지만, 대신 로딩 스피너, 애니메이션 등도 가능!

  // import { lazy, Suspense } from "react";  // 삭제
import dynamic from "next/dynamic";
import TodoList from "./components/TodoList";

// 동적 임포트 + SSR 비활성화
const TodoList1 = dynamic(() => import("./components/TodoList1"), {
  loading: () => <div>Loading....</div>, // 로딩 UI 추가
  ssr: false, // 서버 사이드 렌더링 비활성화 (클라이언트에서만 로드)
});

export default function Home() {
  console.log("sadasdas");
  return (
    <main className="flex min-w-[320px] m-auto my-10 px-5 md:px-5 lg:px-80">
      {/* <Searchbar /> */}
      <TodoList />
      <TodoList1 />
    </main>
  );
}