이전 단계에서는 **Next.js 서버 컴포넌트(Server Components)**를 통해 데이터베이스에 직접 접근함으로써 API 호출 과정 없이 빠른 데이터 로딩을 구현했습니다.
이번에는 데이터가 지연될 때 사용자 경험(UX)을 어떻게 개선할 수 있는지 살펴봅니다.
비동기 환경 구성: async/await 도입 및 지연 시뮬레이션
better-sqlite3는 원래 동기적(synchronous) DB 라이브러리입니다. 하지만 로딩 UI 설명을 위해, 아래처럼 인위적으로 2초의 지연 시간을 추가하여 비동기 상황을 시뮬레이션합니다.
lib/news.js
import sql from 'better-sqlite3';
const db = sql('data.db');
// 동기 DB 접근이지만, UX 설명을 위해 비동기처럼 사용
export async function getAllNews() {
const news = db.prepare('SELECT * FROM news').all();
// 실제 비동기 DB 지연처럼 2초 대기
await new Promise(resolve => setTimeout(resolve, 2000));
return news;
}
app/news/page.js
import { getAllNews } from '@/lib/news';
export default async function NewsPage() {
const news = await getAllNews();
return (
<>
<h1>News Page</h1>
<NewsList news={news} />
</>
);
}
문제 발생: 데이터가 느릴 때 화면이 “멈춘 것처럼” 보임
위 코드처럼 await 때문에 서버 렌더링이 잠시 멈추면, 사용자는 아무런 화면도 보지 못한 채 기다리게 됩니다.
→ 이 상태를 개선하려면 **로딩 화면(Fallback UI)**이 필요합니다.
해결 방법: loading.js로 자동 로딩 UI 제공
Next.js는 페이지에서 비동기 작업이 발생하면 자동으로 Suspense Fallback을 적용할 수 있도록, 같은 경로에 loading.js 파일을 만들면 됩니다.
app/news/loading.js
export default function NewsLoading() {
return <p>Loading...</p>;
}
작동 순서
| 1 | 사용자가 /news 페이지 접근 |
| 2 | NewsPage가 await getAllNews()에서 2초 대기 |
| 3 | Next.js는 기다리지 않고, 먼저 loading.js를 화면에 보여줌 (즉시 렌더링) |
| 4 | 데이터가 완료되면 loading.js → 실제 NewsPage로 자동 교체됨 |
중요한 기술 포인트 (정확하게 이해해야 할 핵심)
| 서버 컴포넌트의 로딩은 클라이언트가 아닌 서버에서 발생 | 즉, HTML 생성 전에 Fallback 화면이 먼저 전송됨 |
| better-sqlite3는 실제로 동기 DB 접근 | 지연 추가는 예시일 뿐이며, 실서비스는 MySQL·PostgreSQL 같은 비동기 DB가 더 적합 |
| loading.js는 React Suspense 기반의 경로별 로딩 UI | page.js와 같은 폴더 또는 상위 폴더에만 적용됨 |
| Edge Runtime 사용 시 sqlite 같은 파일 DB는 사용 불가 | 즉, export const runtime = 'edge'를 사용하는 경우는 주의 필요 |
마무리 정리
✔ 로딩 중 멈춘 것처럼 보이는 문제는 loading.js로 해결할 수 있다.
✔ loading.js는 서버 컴포넌트의 비동기 구간을 자동 감지해 UX를 향상시킨다.
✔ better-sqlite3는 동기 DB이므로 예시는 학습용이다 — 실무에서는 MySQL, MongoDB 같은 비동기 DB를 사용하는 것이 일반적이다.
'NextJS' 카테고리의 다른 글
| [NextJS] Module not found: Can't resolve 'net', Module not found: Can't resolve tls (0) | 2025.10.29 |
|---|---|
| [NextJS] SSR과 Hydration 에러 해결 방법 (0) | 2025.10.21 |
| [NextJS] 서버 컴포넌트에서 DB 직접 접근 (0) | 2025.10.19 |
| [NextJS] 서버 컴포넌트에서 데이터 직접 가져오기 (Server-Side Fetching) (0) | 2025.10.18 |
| [NextJS] 클라이언트 측에서 백엔드 API 데이터 가져오기 (feat. useEffect) (0) | 2025.10.18 |