본문 바로가기
개발 프레임워크/Next.js

[Next.js] 이미지 로딩 처리 3가지 방식과 비교

by minhyeok.lee 2025. 5. 15.
반응형

이미지 로딩 처리 3가지 방식 정리 및 비교

1. Notion, S3, 외부 API 등에서 이미지 URL을 불러올 때, Next.js 프로젝트에서 사용자 친화적으로 제공해야 함

2. 안정적이고 사용자 친화적으로 보여주기 위한 아래 3가지 처리 방식을 정리 및 비교

  1. 단순 오류 처리 (onError fallback)

  2. 로딩 상태 추가 (useState + Spinner)

  3. SSG/SSR 캐싱 방식 고려 (getStaticProps → getServerSideProps)


✅ 방식 1: 단순 오류 처리 (onError fallback)

예제

<Image
  src={imgSrc}
  alt="cover image"
  fill
  onError={() => setImageError(true)}
/>

장점

  • 로딩 실패 시 cover image 텍스트로 대체 가능
  • 구현이 매우 간단함

단점

  • 로딩 중 상태가 없음 (사용자에게 흰 화면)
  • UX가 부족함 (로딩인지 실패인지 구분 어려움)

사용처

  • 내부 이미지나 캐시가 안정적인 환경
  • 필수 이미지가 아니고 대체 가능할 때

✅ 방식 2: 로딩 상태 추가 (useState + Spinner)

예제

{!imageError && !isLoaded ? <Spinner /> : null}
<Image
  src={imgSrc}
  fill
  onLoad={() => setIsLoaded(true)}
  onError={() => setImageError(true)}
/>

장점

  • 로딩 상태 → 성공 → 실패 흐름을 명확히 표현 가능
  • UX 개선: 사용자에게 "지금 로딩 중"이라는 피드백 제공

단점

  • 상태 관리 코드가 늘어남
  • 여러 이미지에 사용 시 로직 재사용 필요 (→ 커스텀 훅 추천)

사용처

  • 사용자 피드백이 중요한 곳 (ex. 갤러리, 포트폴리오)
  • 외부 이미지가 많거나 불안정할 때

✅ 방식 3: SSG/SSR 캐싱 방식 고려 (getStaticProps → getServerSideProps)

Notion이나 S3 이미지 URL은 일정 시간 후 만료되므로, 정적 빌드 시점에 불러오면 만료 후 이미지 깨짐 발생 가능

 

예제

// getStaticProps → getServerSideProps 전환
export const getServerSideProps = async () => {
  const res = await fetch("https://api.notion.com/...");
  const data = await res.json();
  return { props: { data } };
};

장점

  • 이미지 URL을 매 요청 시 실시간으로 갱신
  • 만료 문제 방지

단점

  • 성능: 매 요청마다 서버 실행 → 느릴 수 있음
  • 비용: Vercel, AWS 등에서는 SSR이 리소스를 더 많이 씀

사용처

  • Notion, S3 등 URL 만료 이슈가 있는 API 사용 시
  • 항상 최신 이미지를 보여줘야 하는 페이지

🚀 결론

방식 로딩 중 표시 실패 처리 캐싱 유효성 추천 상황
1번 ❌ 없음 ✅ 텍스트 ❌ 안됨 단순 대체 가능
2번 ✅ Spinner ✅ 텍스트 ❌ 안됨 UX 강조 필요
3번 ✅ 가능 (SSR) ✅ 가능 ✅ 최신 URL Notion, S3 등 외부 URL

💡 확장 팁

  • 🔄 로직 재사용이 많다면 useImageLoader() 훅으로 리팩토링
  • 🌒 다크모드 이미지 대응: resolvedTheme 기반으로 이미지 분기
  • 🗂️ Fallback 이미지: next/imagefallback 기능 또는 직접 구성
반응형

댓글