treeru.com
개발

Next.js <img> vs <Image> — PageSpeed 관점에서의 선택 기준

2026-01-27
Treeru

Next.js를 처음 배우면 "이미지는 무조건 <Image>를 쓰세요"라고 배웁니다. 공식 문서도 그렇게 권장합니다. 하지만 PageSpeed 최적화를 진행하면서 발견한 건, 직접 최적화한 <img> 태그가 더 높은 점수를 내는 경우가 있다는 것입니다.

두 방식의 차이를 이해하면, 상황에 맞는 선택을 할 수 있습니다.

자동
<Image> 방식
수동
<img> 방식
~0.3초
Hero LCP 차이
상황별
적합한 선택

1Next.js Image가 하는 일

next/image의 Image 컴포넌트는 개발자 대신 여러 가지를 자동으로 처리합니다:

자동 리사이즈

원본 이미지에서 여러 크기의 srcset을 자동 생성합니다. 디바이스 너비에 맞는 이미지만 다운로드합니다.

포맷 변환

브라우저가 지원하면 자동으로 WebP로 변환합니다 (AVIF는 별도 설정 필요).

Lazy Loading 기본

viewport 밖 이미지는 자동으로 lazy loading됩니다. priority 속성으로 Hero 이미지만 즉시 로드할 수 있습니다.

CLS 방지

width/height를 필수로 요구해서 이미지 로드 전후 레이아웃 시프트를 방지합니다.

이렇게 보면 만능처럼 보입니다. 하지만 자동화에는 대가가 있습니다.

<!-- Next.js Image가 생성하는 HTML -->
<img
  alt="Hero Image"
  loading="lazy"
  width="900"
  height="1118"
  decoding="async"
  data-nimg="1"
  style="color:transparent"
  sizes="100vw"
  srcset="
    /_next/image?url=%2Fhero.webp&w=640&q=75 640w,
    /_next/image?url=%2Fhero.webp&w=750&q=75 750w,
    /_next/image?url=%2Fhero.webp&w=828&q=75 828w,
    /_next/image?url=%2Fhero.webp&w=1080&q=75 1080w,
    /_next/image?url=%2Fhero.webp&w=1200&q=75 1200w,
    /_next/image?url=%2Fhero.webp&w=1920&q=75 1920w,
    /_next/image?url=%2Fhero.webp&w=2048&q=75 2048w,
    /_next/image?url=%2Fhero.webp&w=3840&q=75 3840w
  "
  src="/_next/image?url=%2Fhero.webp&w=3840&q=75"
/>

srcset에 8개 크기가 들어갑니다. 이미지마다 이런 HTML이 생성되면, document 크기가 커지고, 브라우저는 어떤 크기를 다운로드할지 계산하는 시간이 필요합니다. 또한 /_next/image 엔드포인트를 거치면서 서버에서 실시간 리사이즈가 일어나므로 첫 요청은 느릴 수 있습니다.

2수동 최적화 img 태그

반대로 직접 이미지를 최적화하면 이렇게 됩니다:

// 빌드 시 sharp로 미리 변환
// sharp input.png -resize 900 --avif quality=40 -o hero.avif

<!-- HTML — 깔끔하고 가벼움 -->
<img
  src="/images/hero.avif"
  alt="Hero Image"
  width={900}
  height={1118}
  fetchPriority="high"
  className="object-cover w-full h-full"
/>

HTML이 간결합니다. srcset도 없고, /_next/image 엔드포인트도 거치지 않습니다. 이미지는 이미 최적화된 상태로 /public에 있기 때문에 정적 파일로 바로 서빙됩니다.

수동 최적화의 장점

  • AVIF 사용 가능: Next.js Image는 기본이 WebP입니다. AVIF를 쓰려면 별도 설정이 필요하고, 실시간 인코딩은 느립니다.
  • CDN 캐시 적중률: 정적 파일은 CDN에서 바로 응답합니다. /_next/image는 서버를 거쳐야 합니다.
  • 정확한 품질 제어: 이미지마다 적절한 quality와 크기를 직접 정할 수 있습니다.
  • 빌드 타임 최적화: 한 번 변환하면 끝입니다. 런타임 비용이 없습니다.

3실전 비교

같은 Hero 이미지를 두 방식으로 로드했을 때의 차이입니다.

항목<Image><img> + AVIF
포맷WebP (자동)AVIF (수동)
파일 크기~124KB~60KB
서빙 방식서버 리사이즈 후 응답정적 파일 직접 서빙
첫 요청 응답리사이즈 + 인코딩 대기즉시 응답
HTML 크기srcset 8개 포함 (~500B)단일 src (~80B)
설정 필요거의 없음sharp 스크립트 필요

핵심 차이는 이미지 변환이 언제 일어나는가입니다. Image 컴포넌트는 런타임(사용자 요청 시)에 변환하고, 수동 방식은 빌드 타임에 변환합니다. Hero 이미지처럼 항상 같은 이미지가 보이는 경우, 빌드 타임에 최적화하는 게 더 효율적입니다.

4Image가 적합한 경우

그렇다고 Image 컴포넌트가 나쁜 건 아닙니다. 이미지를 제어할 수 없을 때 진짜 가치를 발휘합니다.

사용자 업로드 이미지

프로필 사진, 게시물 이미지 등 어떤 크기/포맷이 올라올지 모릅니다. Image가 자동으로 리사이즈해줍니다.

CMS 연동 이미지

외부 CMS에서 가져오는 이미지는 크기를 직접 제어할 수 없습니다. remotePatterns와 함께 쓰면 편리합니다.

반응형 아트 디렉션

디바이스마다 다른 크기의 이미지를 보여줘야 할 때, srcset이 자동 생성되는 건 편합니다.

이미지가 수백 장인 경우

블로그 글마다 썸네일이 다르고, 일일이 sharp로 변환하기 번거로운 경우 자동화가 필요합니다.

// ✅ 사용자 업로드 이미지 — Image가 적합
import Image from "next/image";

<Image
  src={user.profileImage}  // 어떤 크기인지 모름
  alt={user.name}
  width={128}
  height={128}
  className="rounded-full object-cover"
/>

// ✅ CMS 이미지 — Image가 적합
<Image
  src={post.thumbnailUrl}  // 외부 URL
  alt={post.title}
  width={800}
  height={450}
  sizes="(max-width: 768px) 100vw, 50vw"
/>

5img가 적합한 경우

반대로, 이미지를 완전히 제어할 수 있을 때는 수동 최적화가 더 좋은 결과를 냅니다.

Hero 이미지 (LCP 요소)

항상 같은 이미지가 표시됩니다. 빌드 타임에 AVIF로 변환하고 fetchPriority='high'와 preload를 쓰면 LCP가 최소화됩니다.

배경 이미지, 아이콘

디자이너가 전달한 에셋을 그대로 사용합니다. 크기와 포맷이 고정되어 있어 자동 리사이즈가 불필요합니다.

정적 사이트 이미지

회사 소개 페이지, 서비스 페이지 등 이미지가 바뀌지 않는 경우. 빌드 시 한 번 최적화하면 런타임 비용이 없습니다.

PageSpeed 점수가 중요한 랜딩 페이지

0.1초라도 더 빠른 LCP가 필요합니다. 서버 리사이즈 과정을 건너뛸 수 있습니다.

// ✅ Hero 이미지 — img + AVIF가 적합
<img
  src="/images/hero.avif"
  alt="서비스 소개"
  width={900}
  height={1118}
  fetchPriority="high"
  className="object-cover w-full h-full"
/>

// ✅ 서비스 카드 이미지 — img + WebP + lazy
<img
  src="/images/service-ai.webp"
  alt="AI 서비스"
  width={1920}
  height={1434}
  loading="lazy"
  className="object-cover w-full h-full"
/>

img 태그 사용 시 주의사항

  • width/height 필수: CLS를 방지하려면 반드시 지정해야 합니다. Image 컴포넌트는 강제하지만, img는 누락하기 쉽습니다.
  • lazy loading 직접 관리: Image는 자동이지만, img는 loading="lazy"를 직접 넣어야 합니다.
  • 최적화를 직접 해야 함: sharp 같은 도구로 빌드 스크립트를 만들어야 합니다. 구체적인 방법은 sharp 자동화를 참고하세요. 귀찮지만 결과는 더 좋습니다.

6선택 기준 정리

결론은 간단합니다. "이미지를 제어할 수 있으면 img, 제어할 수 없으면 Image."

상황추천이유
Hero / LCP 이미지<img> + AVIF최소 용량, 즉시 서빙, preload 가능
정적 에셋 (배경, 아이콘)<img> + WebP고정 크기, 런타임 비용 불필요
사용자 업로드 이미지<Image>크기 불확실, 자동 리사이즈 필요
외부 CMS 이미지<Image>remotePatterns로 외부 URL 처리
이미지 수백 장 (갤러리)<Image>일일이 수동 최적화 비현실적

핵심 정리

Next.js Image는 '편의성', 수동 img는 '성능'에 초점이 맞춰져 있다
Hero 이미지(LCP 요소)는 수동 최적화 img + AVIF가 더 빠르다
사용자 업로드, CMS 등 이미지를 제어할 수 없으면 Image가 적합하다
img 사용 시 width/height, loading='lazy', fetchPriority를 직접 관리해야 한다
하나의 프로젝트에서 두 방식을 혼용해도 된다 — 상황에 맞게 선택

이 글의 비교는 Next.js 15 기준이며, 버전에 따라 Image 컴포넌트의 동작이 다를 수 있습니다. 실제 성능 차이는 서버 환경, CDN 설정, 이미지 크기에 따라 달라집니다.

T

Treeru

웹 개발, IT 인프라, AI 솔루션 분야의 실무 인사이트를 공유합니다. 기업의 디지털 전환을 돕는 IT 파트너, Treeru입니다.

공유

댓글

(4개)
4.63/ 5

로그인하면 댓글을 작성할 수 있습니다.

2026-02-10
4.554.5

결론이 깔끔합니다. '제어 가능하면 img, 불확실하면 Image.' 저도 같은 결론에 도달했는데 이렇게 정리해주니 팀원 설득이 쉬워지겠네요.

2026-02-07
454.0

사용자 업로드 이미지에는 Image가 편하다는 게 핵심이네요. 어떤 이미지가 들어올지 모르니까 자동 리사이즈가 필요한 거고.

2026-02-03
555.0

Image 컴포넌트가 생성하는 srcset이 오히려 HTML을 무겁게 만드는 케이스, 저도 경험했습니다. 정적 사이트에서는 빌드 타임에 최적화하는 게 맞습니다.

관련 글

© 2026 TreeRU. All rights reserved.

본 콘텐츠의 저작권은 TreeRU에 있으며, 출처를 밝히지 않은 무단 전재 및 재배포를 금합니다. 인용 시 출처(treeru.com)를 반드시 명시해 주세요.