Loading UI and Streaming

Odyssey·2025년 1월 13일
0

Next.js_study

목록 보기
11/58
post-thumbnail

2025.1.13 월요일의 공부기록

Next.js에서는 loading.js 파일과 React Suspense를 활용해 로드 중 상태를 처리하고, 사용자 경험을 개선할 수 있다. 로딩 UI와 스트리밍은 사용자가 콘텐츠를 기다리는 동안 의미 있는 피드백을 제공하는 데 도움을 준다.


Loading UI란?

loading.js는 Next.js의 특수 파일로, React Suspense와 통합되어 의미 있는 로딩 UI를 생성할 수 있도록 도와준다.
이 파일은 라우트 세그먼트(route segment)의 콘텐츠가 로드되는 동안 즉시 로드 상태를 표시하며, 로드가 완료되면 새로운 콘텐츠로 자동 교체된다.


작동 방식

  1. 사용자가 특정 경로로 탐색하거나 콘텐츠가 로드 중인 상태일 때:

    • loading.js 파일에서 정의된 로딩 UI가 즉시 렌더링된다.
    • 이 UI는 사용자에게 피드백(스피너, 스켈레톤 등)을 제공한다.
  2. 콘텐츠 로드 완료 시:

    • 로딩 UI는 자동으로 대체되며, 실제 페이지 콘텐츠가 렌더링된다.

로딩 UI의 역할

  • 즉시 피드백 제공:
    콘텐츠가 로드되는 동안 사용자가 빈 화면을 보지 않도록 한다.
  • 의미 있는 대체 UI 표시:
    • 스켈레톤 로딩 애니메이션
    • 스피너
    • 페이지 제목, 이미지 등 간단한 UI를 미리 렌더링

loading.tsx 사용법

기본 파일 구조

app 폴더 하위의 라우트 세그먼트에 loading.tsx 파일을 추가한다.

app/
├── dashboard/
│   ├── loading.tsx   // 대체 UI
│   └── page.tsx     // 실제 페이지

loading.tsx 예제

export default function Loading() {
  return (
    <div style={{ textAlign: "center", marginTop: "50px" }}>
      <p>Loading...</p>
      <div className="spinner"></div>
    </div>
  );
}
  • 동작:
    • /dashboard 경로로 이동하면, 콘텐츠가 로드될 때까지 "Loading..." 메시지와 스피너가 표시된다.
    • 콘텐츠가 로드되면 자동으로 실제 페이지가 렌더링된다.

React Suspense와 스트리밍(Streaming)

React Suspense란?

React Suspense는 React에서 비동기 데이터를 로드하거나, 컴포넌트가 준비될 때까지 로딩 상태를 관리할 수 있도록 하는 기능이다.
Next.js는 Suspense를 활용하여 콘텐츠를 부분적으로 스트리밍하고, 필요할 때 로드된 부분만 즉시 렌더링한다.


스트리밍(Streaming) 렌더링

스트리밍 렌더링은 서버에서 완전히 로드된 콘텐츠를 한 번에 전송하지 않고, 부분적으로 전송하여 즉시 렌더링할 수 있도록 한다.
이를 통해 초기 로드 속도가 빨라지고, 대기 시간이 단축된다.

동작 방식:

  1. 서버는 로딩 가능한 콘텐츠를 즉시 전송한다.
  2. Suspense는 대체 UI(loading.tsx)를 렌더링한다.
  3. 나머지 콘텐츠가 준비되면, 기존 UI를 새로운 콘텐츠로 교체한다.

Suspense와 loading.js 조합 예제

파일 구조

app/
├── dashboard/
│   ├── loading.tsx   // 로딩 UI
│   ├── page.tsx     // 실제 콘텐츠
│   └── components/
│       ├── Stats.tsx // 느리게 로드되는 컴포넌트
│       └── Profile.tsx

코드 예제

page.tsx:

import React, { Suspense } from "react";
import Profile from "./components/Profile";
import Stats from "./components/Stats";

export default function DashboardPage() {
  return (
    <div>
      <h1>Dashboard</h1>
      <Suspense fallback={<p>Loading Profile...</p>}>
        <Profile />
      </Suspense>
      <Suspense fallback={<p>Loading Stats...</p>}>
        <Stats />
      </Suspense>
    </div>
  );
}

Profile.tsx:

export default function Profile() {
  // Simulate delay
  return <p>User Profile Data</p>;
}

Stats.tsx:

export default function Stats() {
  // Simulate delay
  return <p>Dashboard Statistics</p>;
}

동작:

  1. 초기 상태:
    • "Loading Profile..."와 "Loading Stats..."가 표시된다.
  2. Profile 로드 완료:
    • Profile 컴포넌트가 대체 UI를 덮어씌우며 렌더링된다.
  3. Stats 로드 완료:
    • Stats 컴포넌트가 대체 UI를 덮어씌우며 렌더링된다.

Loading UI의 활용 사례

  1. 스켈레톤 로딩
    로딩 상태를 의미 있게 전달하기 위해 실제 콘텐츠의 레이아웃과 비슷한 스켈레톤 UI를 표시.

    export default function Loading() {
      return (
        <div>
          <div className="skeleton-title"></div>
          <div className="skeleton-paragraph"></div>
        </div>
      );
    }
  2. 페이지 전환 시 스피너
    페이지 탐색 중 사용자에게 피드백 제공.

    export default function Loading() {
      return <div className="spinner">Loading...</div>;
    }

6. 장점과 유의점

장점

  1. 사용자 경험 개선
    콘텐츠가 준비되지 않았을 때도 유의미한 UI를 제공하여 사용자 대기 불편을 줄인다.
  2. 빠른 초기 피드백
    사용자는 빈 화면 대신 로딩 UI를 통해 작업 진행 상태를 확인할 수 있다.
  3. 최적화된 리소스 사용
    스트리밍을 통해 필요한 콘텐츠만 부분적으로 렌더링할 수 있다.

유의점

  1. 로딩 상태 남발 주의
    너무 많은 로딩 UI를 사용하면 오히려 UX를 해칠 수 있다.
  2. 스트리밍 환경 지원 여부 확인
    일부 오래된 브라우저나 네트워크 환경에서 스트리밍 렌더링이 제대로 작동하지 않을 수 있다.

0개의 댓글