import Image from 'next/image';
export default function Page() {
return (
<Image
src="/profile.png"
width={500}
height={500}
alt="Picture of the author"
/>
);
}
아래는 <Image>
컴포넌트에서 사용 가능한 props다.
이미지 컴포넌트에는 src
, width
, height
, alt
속성이 필요하다.
import Image from 'next/image';
export default function Page() {
return (
<div>
<Image
src="/profile.png"
width={500}
height={500}
alt="Picture of the author"
/>
</div>
);
}
src
src 속성에는 정적으로 가져온 이미지 파일 또는 경로 문자열을 사용해야한다. loader 속성에 따라 절대적인 외부 URL 또는 내부 경로가 될 수 있다.
외부 URL을 사용하는 경우 next.config.js
의 remotePatterns에 추가해야 한다.
width
width
속성은 픽셀로 표시된 렌더링된 너비를 나타내므로 이미지의 크기에 영향을 준다.
정적으로 가져온 이미지이거나 fill
속성이 있는 이미지를 제외하고는 필수다.
height
height
속성은 픽셀로 표시된 렌더링된 높이를 나타내므로 이미지의 크기에 영향을 줍니다.
정적으로 가져온 이미지이거나 fill
속성이 있는 이미지를 제외하고는 필수다.
alt
alt
속성은 스크린 리더 및 검색 엔진을 위해 이미지를 설명하는 데 사용된다. 이미지가 비활성화되었거나 이미지 로드 중에 오류가 발생한 경우 대체 텍스트로 사용된다.
이미지의 의미를 변경하지 않고 이미지를 대체할 수 있는 텍스트를 포함해야 한다. 이미지를 보충하기 위한 것이 아니며 이미지 위 또는 아래의 캡션에서 이미 제공된 정보를 반복해서는 안된다.
이미지가 순전히 장식적인 목적으로 사용되거나 사용자를 위한 것이 아닌 경우, alt
속성은 빈 문자열 (alt=""
)이어야 한다.
<Image />
컴포넌트는 필수 속성 이외에도 여러 가지 추가 속성을 받을 수 있다.
loader
이미지 URL을 해결하는 데 사용되는 사용자 정의 함수다.
loader
는 다음 매개변수를 사용하여 이미지에 대한 URL 문자열을 반환하는 함수다.
src
width
quality
사용자 정의 로더를 사용하는 예시는 다음과 같다.
import Image from 'next/image';
const imageLoader = ({ src, width, quality }) => {
return `https://example.com/${src}?w=${width}&q=${quality || 75}`;
};
export default function Page() {
return (
<Image
loader={imageLoader}
src="me.png"
alt="Picture of the author"
width={500}
height={500}
/>
);
}
또한 prop을 전달하지 않고 애플리케이션의 모든 next/image
인스턴스를 구성하기 위해 next.config.js
의 loaderFile 구성을 사용할 수도 있다.
fill
부모 요소를 채우도록 이미지를 크기 조정하는 boolean
값이다. 이를 사용하면 width
와 height
를 설정하는 대신 이미지가 부모 요소를 채우게 된다.
fill={true} // {true} | {false}
부모 요소는 position: "relative"
, position: "fixed"
또는 position: "absolute"
스타일을 지정해야 한다.
기본적으로 img 요소는 자동으로 position: "absolute"
스타일이 지정된다.
기본 이미지 맞춤 동작은 이미지를 컨테이너에 맞게 늘리는 것이다. 컨테이너에 맞게 letterbox 처리된 이미지에는 object-fit: "contain"
을 설정하는 것이 좋다. 이렇게 하면 이미지의 가로세로 비율을 유지한 채로 컨테이너에 맞게 표시된다.
또는 object-fit: "cover
"를 사용하면 이미지가 전체 컨테이너를 채우고 가로세로 비율을 유지하기 위해 잘린다. 이를 올바르게 보이려면 overflow: "hidden"
스타일을 부모 요소에 지정해야 한다.
sizes
이미지의 다양한 브레이크포인트에서 이미지의 너비에 대한 정보를 제공하는 문자열이다. sizes
의 값은 fill
을 사용하는 이미지나 반응형 크기를 가진 이미지의 성능에 큰 영향을 미친다.
sizes
속성은 이미지 성능과 관련하여 두 가지 중요한 목적을 제공한다.
sizes
의 값은 브라우저가 next/image
의 자동 생성 소스 세트에서 어떤 크기의 이미지를 다운로드할지 결정하는 데 사용된다. 브라우저가 선택할 때, 페이지에서 이미지의 크기를 아직 알지 못하므로, 뷰포트와 동일한 크기 또는 더 큰 크기의 이미지를 선택한다. sizes
속성을 사용하여 실제로 이미지가 전체 화면보다 작을 것임을 브라우저에 알릴 수 있다. fill
속성이 있는 이미지에서 sizes
값이 지정되지 않은 경우, 기본값으로 100vw
(전체 화면 너비)가 사용된다.
sizes
속성은 next/image
가 자동으로 이미지 소스 세트를 생성하는 방식을 구성한다. sizes
값이 없는 경우, 고정 크기 이미지에 적합한 작은 소스 세트가 생성된다. sizes
가 정의된 경우, 반응형 이미지에 적합한 큰 소스 세트가 생성된다. sizes 속성에 50vw
와 같이 뷰포트 너비의 백분율을 나타내는 크기가 포함된 경우, 소스 세트는 필요하지 않은 값은 포함하지 않도록 자르게 된다.
예를 들어, 스타일링이 모바일 장치에서는 전체 너비로, 태블릿에서는 2열 레이아웃으로, 데스크탑 디스플레이에서는 3열 레이아웃으로 이미지를 표시하는 것을 알고 있다면, 다음과 같은 sizes 속성을 포함해야 한다.
import Image from 'next/image';
export default function Page() {
return (
<div className="grid-element">
<Image
fill
src="/example.png"
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
/>
</div>
);
}
이 예제의 sizes
는 성능 지표에 큰 영향을 줄 수 있다. 33vw
sizes가 없는 경우, 서버에서 선택한 이미지는 실제로 필요한 크기의 3배다. 파일 크기는 너비의 제곱에 비례하므로, sizes
가 없으면 사용자는 필요한 크기보다 9배 큰 이미지를 다운로드하게 된다.
priority
값이 true
인 경우, 이미지는 우선 순위가 높은 이미지로 간주되어 preload된다. preiority
가 있는 이미지를 사용하는 경우, 레이지 로딩은 자동으로 비활성된다.
priority={false} // {false} | {true}
Largest Contentful Paint (LCP) 요소로 감지된 이미지에는 priority
속성을 사용해야 한다. 서로 다른 이미지가 다른 뷰포트 크기에 대한 LCP 요소일 수 있으므로 여러 우선 순위 이미지를 가질 수도 있다.
이 속성은 페이지 로딩 시 화면 상단에 표시되는 이미지에만 사용해야 한다. 기본값은 false
다.
placeholder
이미지가 로드되는 동안 사용할 placeholder다. 가능한 값은 blur
또는 empty
다. 기본값은 empty
다.
placeholder = 'empty'; // {empty} | {blur}
blur
로 설정할 경우, plaehodler로 blurDataURL
속성이 사용된다. src
가 정적 import에서 가져온 객체이고 가져온 이미지가 .jpg
, .png
, .webp
, .avif
인 경우, blurDataURL
은 자동으로 채워진다.
동적 이미지의 경우, blurDataURL
속성을 제공해야 한다. Plaiceholder와 같은 솔루션은 base64
생성에 도움이 될 수 있다.
empty
로 설정할 경우, 이미지가 로드되는 동안 placeholder가 없으며, 빈 공간만 표시된다.
style
기본 이미지 요소에 CSS style을 전달할 수 있다.
const imageStyle = {
borderRadius: '50%',
border: '1px solid #fff',
};
export default function ProfileImage() {
return <Image src="..." style={imageStyle} />;
}
필요한 width
와 height
속성은 스타일링과 상호작용할 수 있다는 점을 기억해야 한다. 이미지의 너비를 수정하기 위해 스타일링을 사용하는 경우, 이미지의 가로세로 비율을 유지하기 위해 height를 auto
로 스타일링해야 한다. 그렇지 않으면 이미지가 왜곡될 수 있다.
onLoadingComplete
이미지가 완전히 로드되고 placeholder가 제거된 후 호출되는 콜백 함수다.
콜백 함수는 <img>
요소에 대한 참조를 포함한 하나의 인수와 함께 호출된다.
<Image onLoadingComplete={(img) => console.log(img.naturalWidth)} />
onLoad
이미지가 로드될 때 호출되는 콜백 함수다.
<Image onLoad={(e) => console.log(e.target.naturalWidth)} />
참고로, load 이벤트는 플레이스홀더가 제거되고 이미지가 완전히 디코딩되기 전에 발생할 수 있다.
대신에 onLoadingComplete
를 사용한다.
onError
이미지 로드 시에 호출되는 콜백 함수다.
<Image onError={(e) => console.error(e.target.id)} />
loading
이미지 로딩 동작이다. 기본값은 lazy
다.
lazy
로 설정할 경우, 이미지가 뷰포트로부터 계산된 거리에 도달할 때까지 이미지 로딩을 지연시킨다.
eager
로 설정할 경우, 이미지를 즉시 로드한다.
loading = 'lazy'; // {lazy} | {eager}
이 속성은 고급 사용 사례에만 적합하다. eager
로 이미지를 로드하는 것은 일반적으로 성능에 해를 입힐 수 있다. 대신에 이미지를 즉시 사전로드하는 priority
속성을 사용하는 것을 권장한다.
blurDataURL
성공적으로 로드되기 전에 src
이미지 대신 사용할 플레이스홀더 이미지로 사용될 데이터 URL다. placeholder="blur"
와 함께 사용될 때에만 효과가 있다.
반드시 base64
로 인코딩된 이미지여야 한다. 이미지는 확대되고 흐려지므로 매우 작은 이미지(10px 이하)를 권장한다. 더 큰 이미지를 플레이스홀더로 사용하면 애플리케이션의 성능에 문제가 발생할 수 있다.
다음을 시도해 보자:
기본 blurDataURL
속성 데모
blurDataURL
속성을 사용한 shimmer 효과 데모
blurDataURL
속성을 사용한 색상 효과 데모
unoptimized
true
로 설정할 경우, 원본 이미지가 품질, 크기 또는 형식을 변경하지 않고 그대로 제공된다. 기본값은 false
다.
unoptimized = {false} // {false} | {true}
import Image from 'next/image';
const UnoptimizedImage = (props) => {
return <Image {...props} unoptimized />;
};
Next.js 12.3.0부터는 다음 구성을 사용하여 next.config.js
를 업데이트하여 모든 이미지에이 속성을 할당할 수 있다.
module.exports = {
images: {
unoptimized: true,
},
};
<Image />
컴포넌트의 다른 속성은 다음을 제외하고 기본적으로 내부 img
요소로 전달된다.
srcSet.
대신 Device Sizes를 사용한다.
decoding
은 항상 "async"
다.
props 외에도 next.config.js
에서 Image 컴포넌트를 구성할 수 있다.
remotePatterns
악의적인 사용자로부터 애플리케이션을 보호하기 위해 외부 이미지 사용에 대한 구성이 필요하다. 이를 위해 Next.js 이미지 최적화 API에서 계정의 외부 이미지만 제공되도록 보장한다. 다음과 같이 next.config.js
파일의 remotePatterns
속성으로 외부 이미지를 구성할 수 있다.
// next.config.js
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: 'example.com',
port: '',
pathname: '/account123/**',
},
],
},
};
위의 예제는 next/image
의 src
속성이 https://example.com/account123/
로 시작해야 함을 보장한다. 다른 프로토콜, 호스트명, 포트 또는 일치하지 않는 경로는 400 Bad Request
로 응답한다.
다음은 next.config.js
파일의 remotePatterns
속성에 대한 또 다른 예제다.
module.exports = {
images: {
remotePatterns: [
{
protocol: 'https',
hostname: '**.example.com',
},
],
},
};
위의 예제에서는 https://img1.example.com
또는 https://me.avatar.example.com
으로 시작하는 src
속성을 허용한다. 또한 임의의 수의 하위 도메인을 허용한다. 다른 프로토콜이나 일치하지 않는 호스트명은 400 Bad Request
로 응답한다.
*
는 단일 경로 세그먼트 또는 서브도메인을 일치시킨다.
**
는 끝에서 경로 세그먼트의 임의의 수 또는 시작에서 서브도메인의 임의의 수를 일치시킨다.
**
구문은 패턴의 중간에서 작동하지 않는다.
domains
remotePatterns
와 유사하게, domains
구성은 외부 이미지에 대한 허용된 호스트명 목록을 제공하는 데 사용될 수 있다.
하지만 domains
구성은 와일드카드 패턴 일치를 지원하지 않으며 프로토콜, 포트 또는 경로를 제한할 수 없다.
악의적인 사용자로부터 애플리케이션을 보호하기 위해 domains
대신 strict remotePatterns
를 구성하는 것을 권장한다. domains
는 도메인에서 제공되는 모든 콘텐츠를 소유한 경우에만 사용한다.
다음은 next.config.js
파일의 domains
속성 예제다.
module.exports = {
images: {
domains: ['assets.acme.com'],
},
};
loaderFile
Next.js의 내장된 이미지 최적화 API 대신 클라우드 제공업체를 사용하여 이미지를 최적화하려는 경우, 다음과 같이 next.config.js
에서 loaderFile
을 구성할 수 있다.
module.exports = {
images: {
loader: 'custom',
loaderFile: './my/image/loader.js',
},
};
이는 Next.js 애플리케이션의 루트와 상대적인 파일을 가리켜야 한다. 파일은 문자열을 반환하는 기본 함수를 내보내야 한다. 아래 예제를 참고한다.
export default function myImageLoader({ src, width, quality }) {
return `https://example.com/${src}?w=${width}&q=${quality || 75}`;
}
또는 next/image
의 각 인스턴스를 구성하기 위해 loader
prop을 사용할 수도 있다.
다음 구성은 고급 사용 사례를 위한 것으로 일반적으로 필요하지 않다. 아래의 속성을 구성하는 경우, 향후 업데이트에서 Next.js의 기본값을 재정의한다.
deviceSizes
사용자의 기대하는 장치 너비를 알고 있다면, next.config.js
의 deviceSizes
속성을 사용하여 장치 너비에 대한 목록을 지정할 수 있다. 이러한 너비는 next/image
컴포넌트가 sizes
prop을 사용할 때 사용되며, 사용자의 장치에 적합한 이미지가 제공된다.
구성을 제공하지 않으면 아래의 기본값을 사용한다.
module.exports = {
images: {
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
},
};
imageSizes
next.config.js
파일에서 images.imageSizes
속성을 사용하여 이미지 너비의 목록을 지정할 수 있다. 이러한 너비는 장치 너비 배열과 연결되어 이미지 srcset을 생성하는 데 사용된다.
두 개의 별도 목록을 사용하는 이유는 imageSizes가 sizes
prop을 제공하는 이미지에만 사용되기 때문이다. sizes
prop은 이미지가 화면의 전체 너비보다 작음을 나타낸다. 따라서 imageSizes의 크기는 deviceSizes의 가장 작은 크기보다 작아야 한다.
구성을 제공하지 않으면 아래의 기본값을 사용한다.
module.exports = {
images: {
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
},
};
formats
기본 이미지 최적화 API는 요청의 Accept
헤더를 통해 브라우저에서 지원하는 이미지 형식을 자동으로 감지한다.
Accept
헤더가 구성된 형식과 일치하는 경우, 배열에서 첫 번째 일치 항목이 사용된다. 따라서 배열의 순서가 중요하다. 일치하는 항목이 없는 경우 (또는 소스 이미지가 애니메이션인 경우), 이미지 최적화 API는 원본 이미지 형식으로 대체된다.
구성을 제공하지 않으면 아래의 기본값을 사용한다.
module.exports = {
images: {
formats: ['image/webp'],
},
};
다음 구성으로 AVIF
지원을 활성화할 수 있다.
module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
},
};
일반적으로 AVIF
는 인코딩에 20% 더 오래 걸리지만 WebP
에 비해 20% 더 작게 압축된다. 이는 이미지가 처음 요청될 때 일반적으로 느리게 작동하고, 그 후 캐시된 요청은 더 빠르게 작동할 것을 의미한다.
Next.js 앞에 Proxy/CDN을 사용하여 자체 호스팅하는 경우, Proxy가 Accept
헤더를 전달하도록 구성해야 한다.
이미지는 요청 시 동적으로 최적화되고 <distDir>/cache/images
디렉터리에 저장된다. 최적화된 이미지 파일은 만료될 때까지 후속 요청에 대해 제공된다. 캐시된 만료된 파일과 일치하는 요청이 들어오면, 만료된 이미지가 즉시 제공된다. 그런 다음 이미지는 다시 최적화되며, 백그라운드에서 캐시에 새로운 만료 날짜로 저장된다.(이를 재유효화라고도 함)
이미지의 캐시 상태는 x-nextjs-cache
응답 헤더의 값으로 확인할 수 있다. 가능한 값은 다음과 같다.
MISS
: 경로가 캐시에 없음 (첫 번째 방문 시 최대 한 번 발생)
STALE
: 경로가 캐시에 있지만 재유효화 시간을 초과하여 백그라운드에서 업데이트됨
HIT
: 경로가 캐시에 있고 재유효화 시간을 초과하지 않음
만료 시간 (혹은 Max Age)은 minimumCacheTTL
구성 또는 상위 이미지의 Cache-Control
헤더 중 더 큰 값에 의해 정의된다. 구체적으로는 Cache-Control
헤더의 max-age
값을 사용한다. s-maxage
와 max-age
둘 다 발견되면 s-maxage
가 우선한다. max-age
는 CDN과 브라우저를 포함한 하위 클라이언트로 전달된다.
upstream 이미지에 Cache-Control
헤더가 포함되지 않거나 값이 매우 낮은 경우 캐시 지속 시간을 늘리기 위해 minimumCacheTTL
을 구성할 수 있다.
deviceSizes
와 imageSizes
를 구성하여 생성 가능한 이미지 수를 줄일 수 있다.
formats
를 구성하여 여러 형식을 비활성화하고 단일 이미지 형식을 선호할 수 있다.
minimumCacheTTL
캐시된 최적화된 이미지의 TTL(Time to Live)을 초 단위로 구성할 수 있다. 많은 경우에는 파일 내용을 자동으로 해싱하고 불변
의 Cache-Control
헤더로 이미지를 영구적으로 캐시하는 정적 이미지 가져오기를 사용하는 것이 좋다.
module.exports = {
images: {
minimumCacheTTL: 60,
},
};
최적화된 이미지의 만료 시간 (또는 Max Age)은 minimumCacheTTL
또는 상위 이미지의 Cache-Control
헤더 중 더 큰 값에 의해 정의된다.
이미지별로 캐싱 동작을 변경해야 하는 경우, headers
를 구성하여 상위 이미지에 Cache-Control
헤더를 설정할 수 있다. (예: /some-asset.jpg
, /_next/image
자체가 아닌)
현재 캐시를 무효화하는 메커니즘이 없으므로, minimumCacheTTL
을 낮게 유지하는 것이 좋다. 그렇지 않으면 src
prop을 수동으로 변경하거나 <distDir>/cache/images
를 삭제해야 할 수도 있다.
disableStaticImages
기본 동작은 import icon from './icon.png
과 같은 정적 파일을 가져와 src
속성에 전달하는 것을 허용한다.
다른 플러그인과 충돌하는 경우에는 이 기능을 비활성화하고 다른 방식으로 가져오기를 기대하는 경우가 있을 수 있다.
next.config.js
에서 정적 이미지 가져오기를 비활성화할 수 있다.
module.exports = {
images: {
disableStaticImages: true,
},
};
dangerouslyAllowSVG
디폴트 loader는 몇 가지 이유로 SVG 이미지를 최적화하지 않는다. 첫째로, SVG는 벡터 형식이므로 손실 없이 크기를 조정할 수 있다. 둘째로, SVG는 HTML/CSS와 많은 기능을 공유하기 때문에 적절한 콘텐츠 보안 정책 (CSP) 헤더가 없으면 취약점이 발생할 수 있다.
기본 이미지 최적화 API를 사용하여 SVG 이미지를 제공해야 하는 경우, next.config.js
에서 dangerouslyAllowSVG
를 설정할 수 있다.
module.exports = {
images: {
dangerouslyAllowSVG: true,
contentDispositionType: 'attachment',
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
},
};
또한, 브라우저가 이미지를 다운로드하도록 contentDispositionType
을 설정하는 것과 이미지에 포함된 스크립트가 실행되지 않도록 contentSecurityPolicy
를 설정하는 것을 강력히 권장한다.
디폴트 loader는 자동으로 애니메이션 이미지를 이미지 최적화 우회하고 원본 이미지 그대로 제공한다.
애니메이션 파일에 대한 자동 감지는 최선을 다하며 GIF, APNG, WebP를 지원한다. 특정 애니메이션 이미지에 대해 명시적으로 이미지 최적화를 우회하려면 unoptimized
prop을 사용한다.
이 next/image
컴포넌트는 브라우저의 네이티브 지연 로딩을 사용하며, 이는 Safari 15.4 이전의 오래된 브라우저에서 즉시 로딩으로 대체될 수 있다. 희미한 placeholder를 사용하는 경우, Safari 12 이전의 오래된 브라우저는 빈 placeholder로 대체될 수 있다. weight
/height
가 자동(auto)인 스타일을 사용하는 경우, 종횡비를 유지하지 않는 Safari 15 이전의 오래된 브라우저에서 레이아웃 이동(Layout Shift)이 발생할 수 있다.
Safari 15 및 16은 로딩 중에 회색 테두리를 표시한다. Safari 16.4에서 이 문제가 수정되었다. 가능한 해결책은 다음과 같다.
CSS @supports (font: -apple-system-body) 및 (-webkit-appearance: none)을 사용하여 img[loading="lazy"] { clip-path: inset(0.6px) }
를 지정한다.
이미지가 화면에 표시되는 영역 위에 위치한다면 priority
를 사용한다.
Firefox 67 이상에서는 로딩 중에 흰색 배경이 표시된다. 가능한 해결책은 다음과 같다.
AVIF format
을 활성화한다.
placeholder="blur"
을 사용한다.
[ 출처 ]
https://nextjs.org/docs/app/api-reference/components/image#caching-behavior