코드도보통지

3관문. Streaming & Suspense

관문 3 / 7

loading.js와 Suspense 경계를 전략적으로 배치하여 빠른 TTFB와 점진적 UI 로딩을 구현하라.

📖 이론 비급

Streaming: 준비된 것부터 전송

전통적인 SSR은 모든 데이터가 준비될 때까지 HTML 전송을 기다린다. Streaming은 준비된 부분부터 즉시 전송하고, 느린 부분은 나중에 채운다.

Next.js 구현:

  • loading.js: 라우트 수준 Suspense 경계, 자동으로 적용
  • <Suspense fallback={<Skeleton />}>: 컴포넌트 수준 세밀한 제어
  • 느린 컴포넌트를 Suspense로 감싸면 나머지 UI가 먼저 표시된다

⚔️ 수련 코드

// app/dashboard/page.js
import { Suspense } from 'react';
import { Skeleton } from '@/components/ui/skeleton';

// 빠른 데이터 (즉시 렌더)
async function QuickStats() {
  const data = await fetch('/api/quick-stats').then(r => r.json());
  return <div>방문자: {data.visitors}</div>;
}

// 느린 데이터 (3초 소요)
async function SlowChart() {
  await new Promise(r => setTimeout(r, 3000)); // 느린 DB 쿼리
  return <div>차트 데이터 로드 완료</div>;
}

export default function DashboardPage() {
  return (
    <div>
      <h1>대시보드</h1>
      {/* QuickStats는 즉시 표시 */}
      <QuickStats />

      {/* TODO: SlowChart를 Suspense로 감싸라
          fallback으로 Skeleton을 표시하여
          빠른 컨텐츠가 차트를 기다리지 않도록 하라 */}
      <SlowChart />
    </div>
  );
}