Next.js Image Optimization (Images) 정리
Next.js Docs – Getting Started: Images (Image Optimization) 페이지를 기반으로, App Router 환경에서의 이미지 사용 및 최적화 방식을 정리한 문서입니다.
1. 개요
Next.js의 <Image> 컴포넌트는 기본 HTML <img> 요소를 확장하여 다음과 같은 기능을 제공합니다.
- 크기 최적화 (Size optimization)
- 기기별로 알맞은 크기의 이미지를 자동으로 제공하고, WebP 등 최신 포맷을 사용합니다.
- 시각적 안정성 (Visual stability)
- 이미지 로딩 중 레이아웃이 튀는 현상(Layout Shift, CLS)을 자동으로 방지합니다.
- 더 빠른 페이지 로딩 (Faster page loads)
- 뷰포트에 들어올 때만 이미지를 로드하는 브라우저 네이티브 lazy loading을 사용하고,
선택적으로 블러(blur-up) 플레이스홀더를 제공합니다.
- 뷰포트에 들어올 때만 이미지를 로드하는 브라우저 네이티브 lazy loading을 사용하고,
- 유연한 에셋 관리 (Asset flexibility)
- 원격(리모트) 서버에 있는 이미지도 필요할 때 크기를 변경하며 사용할 수 있습니다.
기본적인 사용은 다음과 같습니다.
// app/page.tsx
import Image from 'next/image'
export default function Page() {
return <Image src="" alt="" />
}
src에는 로컬 이미지 경로 또는 원격 이미지 URL을 사용할 수 있습니다.
2. Local Images (로컬 이미지)
2.1 public 디렉터리 사용
정적인 파일(이미지, 폰트 등)은 프로젝트 루트에 있는 public 폴더 아래에 둘 수 있습니다.
my-app/
app/
public/
profile.png
public내부 파일은 기본 URL(/)을 기준으로 경로를 지정합니다.
// app/page.tsx
import Image from 'next/image'
export default function Page() {
return (
<Image
src="/profile.png"
alt="Picture of the author"
width={500}
height={500}
/>
)
}
- 여기서:
src="/profile.png"→public/profile.png를 가리킴width,height는 브라우저가 이미지 비율과 레이아웃을 미리 알 수 있도록 해 주어
CLS(Cumulative Layout Shift)를 방지합니다.
2.2 정적 Import 사용
이미지를 정적으로 import 하면, Next.js가 빌드 시점에 해당 이미지의 intrinsic width / height와 블러 데이터(blurDataURL)를 자동으로 계산해 줍니다.
// app/page.tsx
import Image from 'next/image'
import ProfileImage from './profile.png'
export default function Page() {
return (
<Image
src={ProfileImage}
alt="Picture of the author"
// width={500} 자동 제공
// height={500} 자동 제공
// blurDataURL="data:..." 자동 제공
// placeholder="blur" // 로딩 중 블러 처리 (선택)
/>
)
}
- 정적 import를 사용하면:
width,height를 명시하지 않아도 됩니다.blurDataURL이 자동 생성되어,placeholder="blur"만 추가해도 부드러운 블러 로딩 효과를 사용할 수 있습니다.- CLS 방지에 유리하고, 코드도 간결해집니다.
3. Remote Images (원격 이미지)
3.1 기본 사용
원격 이미지를 사용하려면 src에 절대 URL 문자열을 전달합니다.
// app/page.tsx
import Image from 'next/image'
export default function Page() {
return (
<Image
src="https://s3.amazonaws.com/my-bucket/profile.png"
alt="Picture of the author"
width={500}
height={500}
/>
)
}
- 원격 이미지는 빌드 시점에 파일에 접근할 수 없기 때문에,
- 반드시
width와height(또는fill)를 명시해야 합니다. - 필요한 경우 **
blurDataURL**도 직접 전달해야 합니다.
- 반드시
width와height는 이미지의 가로세로 비율을 계산하는 데 사용되며,
로딩 중 레이아웃이 튀는 것을 방지하는 데 필수적입니다.
3.2 fill 속성 사용
정확한 픽셀 크기 대신, 부모 요소의 크기를 채우도록 만들고 싶다면 fill 속성을 사용할 수 있습니다.
// 예시: 부모 컨테이너를 기준으로 꽉 차게 렌더링
<div style={{ position: 'relative', width: 400, height: 300 }}>
<Image
src="https://s3.amazonaws.com/my-bucket/profile.png"
alt="Picture of the author"
fill
style={{ objectFit: 'cover' }}
/>
</div>
- 이 경우 부모 요소에 **고정된 width/height와
position: relative**가 설정되어 있어야 합니다. <Image>는 내부적으로position: absolute로 렌더링되어 부모를 채웁니다.
3.3 next.config.js의 remotePatterns 설정
보안과 오용 방지를 위해, Next.js에서는 허용된 원격 이미지 도메인/경로를 명시적으로 지정해야 합니다.
이를 위해 next.config.js 또는 next.config.ts에서 images.remotePatterns를 설정합니다.
// next.config.ts
import type { NextConfig } from 'next'
const config: NextConfig = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 's3.amazonaws.com',
port: '',
pathname: '/my-bucket/**',
search: '',
},
],
},
}
export default config
- 위 설정은 다음과 같이 동작합니다.
- 프로토콜:
https - 호스트:
s3.amazonaws.com - 경로:
/my-bucket/**(특정 버킷 아래 경로만 허용) - 쿼리:
search: ''(쿼리 스트링 없음)
- 프로토콜:
보안을 위해 가능한 한 구체적인 패턴을 사용하는 것이 권장됩니다.
그렇지 않으면, 악의적인 사용자가 예기치 않은 도메인/경로의 이미지를 최적화 서버로 보내는 식으로 남용할 수 있습니다.
4. Image 컴포넌트가 제공하는 최적화 요약
Next.js next/image 컴포넌트는 다음과 같은 최적화를 자동으로 처리합니다.
-
크기 및 포맷 최적화
- 뷰포트 크기, DPR(디바이스 픽셀 비율)에 따라 알맞은 이미지 크기를 제공
- WebP 등의 최신 포맷을 자동으로 사용
-
레이아웃 안정성
width/height또는fill+ 부모 컨테이너의 크기를 기반으로 레이아웃을 먼저 잡고 이미지를 로딩- CLS를 줄이는 데 큰 도움
-
Lazy Loading
- 뷰포트 외부의 이미지는 필요할 때까지 로딩하지 않음
- 초기 페이지 로드 성능 향상
-
Blur-up Placeholder (선택)
placeholder="blur"와blurDataURL을 사용하면,
저해상도 블러 이미지를 먼저 보여주고 이후 고해상도로 교체하는 패턴을 쉽게 구현 가능
-
로컬/원격 이미지 통합 관리
public폴더 내부 정적 파일, 정적 import, 원격 URL 이미지를 모두 동일한 컴포넌트로 처리
자세한 속성 목록과 고급 기능은 Image Component API Reference에서 확인할 수 있습니다.