Next API : next/image

hwisaac·2023년 3월 12일
0

NextJS API(page router)

목록 보기
1/10

참고: 이 페이지는 next/image 컴포넌트의 API 참조 문서입니다. 기능 개요 및 사용 정보에 대해서는 Image ComponentImage Optimization 문서를 참조하세요.

참고: Next.js 13 이전 버전을 사용하는 경우, 컴포넌트 이름이 변경되어 next/legacy/image 문서를 사용해야 합니다.

next/image 컴포넌트는 브라우저 기본 레이지 로딩을 사용하며, Safari 15.4 이전 버전의 오래된 브라우저에서는 빠른 로딩으로 대체될 수 있습니다. 블러업(Blur-up) 플레이스홀더를 사용하는 경우, Safari 12 이전 버전의 오래된 브라우저에서는 빈 플레이스홀더로 대체됩니다. 너비/높이가 자동(auto)인 스타일을 사용하는 경우, 가로 세로 비율을 보존하지 않는 Safari 15 이전 버전의 오래된 브라우저에서 레이아웃 쉬프트(Layout Shift)를 발생시킬 수 있습니다. 자세한 내용은 MDN 비디오를 참조하세요.

알려진 브라우저 버그

  • Safari 15 이상에서 로딩 중에 회색 테두리가 표시됩니다. 가능한 해결책:
    • CSS @supports (font: -apple-system-body) and (-webkit-appearance: none) { img[loading="lazy"] { clip-path: inset(0.6px) } } 사용
    • 이미지가 위쪽에 위치한 경우 우선순위 사용
  • Firefox 67 이상에서 로딩 중에 흰색 배경이 표시됩니다. 가능한 해결책:
    • AVIF 형식 활성화
    • placeholder="blur" 사용

필수 Props

<Image /> 컴포넌트는 다음 속성을 필요로 합니다.

src

다음 중 하나여야 합니다:

  1. 정적으로 가져온 이미지 파일 또는
  2. 경로 문자열. 이는 로더(prop)에 따라 외부 URL이나 내부 경로가 될 수 있습니다.

외부 URL을 사용할 경우, next.config.jsremotePatterns에 추가해야 합니다.

width

width 속성은 픽셀 단위로 렌더링 된 너비를 나타내므로 이미지가 얼마나 크게 보이는지에 영향을 미칩니다.

정적으로 가져온 이미지나 fill 속성을 가진 이미지를 제외하고는 필수입니다.

height

height 속성은 픽셀 단위로 렌더링된 높이를 나타내므로 이미지가 얼마나 크게 보이는지에 영향을 미칩니다.

정적으로 가져온 이미지나 fill 속성을 가진 이미지를 제외하고는 필수입니다.

alt

alt 속성은 스크린 리더 및 검색 엔진을 위해 이미지를 설명하는 데 사용됩니다. 이미지가 비활성화되거나 이미지 로딩 중에 오류가 발생한 경우 대체 텍스트로 사용됩니다.

페이지의 의미를 변경하지 않고 이미지를 대체할 수 있는 텍스트를 포함해야 합니다. 이미지를 보충하는 용도로 사용되어서는 안 되며 이미지 위나 아래 캡션에서 이미 제공된 정보를 반복해서는 안 됩니다.

만약 이미지가 순전히 장식적인 목적이거나 사용자를 위한 것이 아닌 경우, alt 속성은 빈 문자열(alt="")이어야 합니다.

더 알아보기(https://html.spec.whatwg.org/multipage/images.html#alt)

Optional Props

<Image /> 컴포넌트는 필수 속성 외에도 여러 가지 선택적 속성을 받을 수 있습니다. 이 섹션에서는 Image 컴포넌트에서 가장 일반적으로 사용되는 속성을 설명합니다. Advanced Props 섹션에서 덜 일반적으로 사용되는 속성에 대한 자세한 정보를 찾을 수 있습니다.

loader

이미지 URL을 해결하는 데 사용되는 사용자 정의 함수입니다.

로더는 다음 매개변수를 받고 이미지에 대한 URL 문자열을 반환하는 함수입니다.

  • src
  • width
  • quality
    사용자 정의 로더의 예시는 다음과 같습니다.
import Image from 'next/image'

const myLoader = ({ src, width, quality }) => {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

const MyImage = (props) => {
  return (
    <Image
      loader={myLoader}
      src="me.png"
      alt="Picture of the author"
      width={500}
      height={500}
    />
  )
}

또는 loaderFile 구성을 사용하여 prop을 전달하지 않고 응용 프로그램에서 next/image의 모든 인스턴스를 구성할 수 있습니다.

fill

이미지가 너비와 높이를 설정하는 대신 부모 요소를 채우도록 하는 부울입니다.

부모 요소는 position: "relative", position: "fixed" 또는 position: "absolute" 스타일을 할당해야 합니다.

img 요소는 기본적으로 position: "absolute" 스타일이 자동으로 지정됩니다.

기본 이미지 적합 동작은 컨테이너에 맞게 이미지를 늘리는 것입니다. 컨테이너에 대한 letterbox 된 이미지를 원하는 경우 object-fit: "contain"을 설정하여 측면 비율을 유지합니다.

대신, object-fit: "cover"를 사용하면 이미지가 전체 컨테이너를 채우고 측면 비율을 유지하면서 잘릴 수 있습니다. 이것이 올바르게 보이려면 overflow: "hidden" 스타일이 부모 요소에 할당되어야 합니다.

참고:

sizes

sizes는 이미지가 렌더링될 때 어떤 breakpoints에서 이미지가 얼마나 넓어질지에 대한 정보를 제공하는 문자열입니다. sizes의 값은 fill을 사용하거나 반응형 크기를 가진 이미지의 성능에 큰 영향을 미칩니다.

sizes 속성은 이미지 성능과 관련하여 두 가지 중요한 목적을 제공합니다:

  1. 첫째로, 브라우저는 next/image에서 자동 생성된 소스셋에서 어떤 크기의 이미지를 다운로드할지 결정하는 데 sizes의 값을 사용합니다.

브라우저는 아직 페이지에서 이미지의 크기를 모르므로 보이는 화면과 같거나 더 큰 크기의 이미지를 선택합니다. sizes 속성은 브라우저에게 이미지가 전체 화면보다 작을 것임을 알려줍니다. fill 속성을 사용한 이미지에서 sizes 값을 지정하지 않으면 기본값으로 100vw (전체 화면 너비)가 사용됩니다.

  1. 둘째로, sizes 속성은 next/image가 자동으로 생성하는 이미지 소스셋을 구성합니다.

sizes 값이 없으면 고정 크기 이미지에 적합한 작은 소스셋이 생성됩니다. sizes가 정의되면 반응형 이미지에 적합한 큰 소스셋이 생성됩니다. 만약 sizes 속성이 50vw와 같은 viewport width의 백분율을 포함하는 경우, 소스셋은 필요하지 않은 값은 포함하지 않도록 자르게 됩니다.

예를 들어, 모바일 기기에서 이미지가 전체 너비로, 태블릿에서는 2열 레이아웃으로, 데스크톱 디스플레이에서는 3열 레이아웃으로 렌더링될 것임을 알고 있다면, 다음과 같은 sizes 속성을 포함해야 합니다:

import Image from 'next/image'
const Example = () => (
  <div className="grid-element">
    <Image
      src="/example.png"
      fill
      sizes="(max-width: 768px) 100vw,
              (max-width: 1200px) 50vw,
              33vw"
    />
  </div>
)

이 예제 sizes는 성능 지표에 큰 영향을 미칠 수 있습니다. 33vw sizes가 없으면 서버에서 선택된 이미지는 필요한 것보다 3배 넓을 것입니다. 파일 크기는 폭의 제곱에 비례하기 때문에 sizes가 없으면 사용자는 필요한 것보다 9배 큰 이미지를 다운로드하게 됩니다.

srcsetsizes에 대해 자세히 알아보세요:

quality

최적화된 이미지의 품질을 나타내는 정수 값입니다. 1에서 100까지의 값을 가질 수 있으며, 100은 가장 좋은 품질이므로 파일 크기가 가장 큽니다. 기본값은 75입니다.

priority

true인 경우, 이미지는 높은 우선순위로 처리되어 preload됩니다. 우선순위가 있는 이미지에 대해서만 lazy loading이 자동으로 비활성화됩니다.

Largest Contentful Paint (LCP) 요소로 감지된 모든 이미지에 priority 속성을 사용해야 합니다. 서로 다른 뷰포트 크기에 대해 LCP 요소가 다른 경우 여러 우선순위 이미지를 사용하는 것이 적절할 수 있습니다.

이미지가 화면 상단에 보이는 경우에만 사용해야 합니다. 기본값은 false입니다.

placeholder

이미지가 로딩되는 동안 사용할 플레이스홀더입니다. blur 또는 empty 값을 가질 수 있습니다. 기본값은 empty입니다.

blur 값인 경우, blurDataURL 속성이 플레이스홀더로 사용됩니다. 만약 src가 정적인 import 객체이고 가져온 이미지가 .jpg, .png, .webp, 또는 .avif인 경우, blurDataURL이 자동으로 채워집니다.

동적 이미지의 경우, blurDataURL 속성을 제공해야 합니다. Plaiceholder와 같은 솔루션은 base64 생성을 돕습니다.

empty인 경우, 이미지가 로딩되는 동안 플레이스홀더가 없으며, 빈 공간만 표시됩니다.

다음을 확인하세요:

고급 Props

일부 경우에는 더 고급 사용법이 필요할 수 있습니다. <Image /> 컴포넌트는 다음과 같은 고급 프로퍼티를 선택적으로 받아들입니다.

style

하위 이미지 요소에 CSS 스타일을 전달할 수 있습니다.

또한 필수적인 widthheight props는 스타일링과 상호작용할 수 있습니다. 이미지의 너비를 수정하기 위해 스타일링을 사용하는 경우, height="auto" 스타일도 설정해야하며, 그렇지 않으면 이미지가 왜곡됩니다.

onLoadingComplete

이미지가 완전히 로드되고 placeholder가 제거된 후에 호출되는 콜백 함수입니다.

콜백 함수는 하나의 인수, 하위 <img> 요소에 대한 참조를 가지고 호출됩니다.

onLoad

이미지가 로드될 때 호출되는 콜백 함수입니다.

로드 이벤트가 placeholder가 제거되고 이미지가 완전히 디코딩되기 전에 발생할 수 있음에 유의하십시오.

onLoadingComplete를 사용하세요.

onError

이미지 로드에 실패할 경우 호출되는 콜백 함수입니다.

loading

주의: 이 프로퍼티는 고급 사용자를 위한 것입니다. 이미지를 eager(즉시로드)로 변경하는 것은 대개 성능을 저하시킵니다.

우리는 대부분의 사용 사례에 적절하게 이미지를 즉시로드하기 위해 우선순위 프로퍼티를 사용하는 것을 권장합니다.

이미지 로드 동작을 나타내는 프로퍼티입니다. 기본값은 lazy입니다.

lazy인 경우, 뷰포트에서 일정 거리까지 이미지 로드를 지연합니다.

eager인 경우, 이미지를 즉시 로드합니다.

Learn more

blurDataURL

src 이미지가 성공적으로 로드되기 전에 placeholder 이미지로 사용되는 Data URL입니다. placeholder="blur"와 함께 사용될 때에만 효과가 있습니다.

base64로 인코딩된 이미지여야 합니다. 매우 작은 이미지(10px 이하)를 권장합니다. 큰 이미지를 placeholder로 사용하면 응용 프로그램 성능이 저하될 수 있습니다.

실습해보기

일치하는 이미지에 대한 단색 Data URL(https://png-pixel.com/) 생성해보기

unoptimized

unoptimizedtrue인 경우, 원본 이미지를 크기, 품질, 포맷 변경 없이 그대로 사용합니다. 기본값은 false입니다.

import Image from 'next/image'

const UnoptimizedImage = (props) => {
  return <Image {...props} unoptimized />
}

Next.js 12.3.0부터 다음 구성을 사용하여 모든 이미지에 이 속성을 할당할 수 있습니다.

module.exports = {
  images: {
    unoptimized: true,
  },
}

기타 속성

<Image /> 구성 요소의 다른 속성은 다음과 같습니다. srcSet를 제외한 모든 속성은 내부 img 요소에 전달됩니다.

  • srcSet. Device Sizes를 사용하세요.
  • decoding. 항상 "async"입니다.

구성 옵션

Remote Patterns

외부 이미지를 사용하려면 구성이 필요합니다. 이를 통해 Next.js 이미지 최적화 API에서 사용자 지정 도메인의 이미지만 서비스하도록 보호할 수 있습니다. remotePatterns 속성을 사용하여 next.config.js 파일에서 구성할 수 있습니다.

module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
        port: '',
        pathname: '/account123/**',
      },
    ],
  },
}

참고: 위의 예제는 next/imagesrc 속성이 https://example.com/account123/로 시작해야 한다는 것을 보장합니다. 다른 프로토콜, 호스트 이름, 포트 또는 일치하지 않는 경로는 400 Bad Request로 응답합니다.

다음은 next.config.js 파일에서 remotePatterns 속성의 또 다른 예입니다.

module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.example.com',
      },
    ],
  },
}

참고: 위의 예제는 next/imagesrc 속성이 https://img1.example.com 또는 https://me.avatar.example.com 또는 어떤 하위 도메인이라도 시작해야 한다는 것을 보장합니다. 다른 프로토콜이나 일치하지 않는 호스트 이름은 400 Bad Request로 응답합니다.

와일드카드 패턴은 경로명과 호스트명 둘 다 사용할 수 있으며 다음과 같은 구문을 갖습니다:

  • * : 하나의 경로 세그먼트 또는 서브도메인과 일치합니다.
  • ** : 끝에서 경로 세그먼트의 모든 수 또는 서브도메인과 일치합니다.
    ** 구문은 패턴의 중간에서 작동하지 않습니다.

도메인

참고: 프로토콜과 경로를 제한할 수 있도록 remotePatterns를 사용하는 것이 좋습니다.

remotePatterns과 유사하게 domains 구성은 외부 이미지에 대한 허용된 호스트 이름 목록을 제공하는 데 사용할 수 있습니다.

그러나 domains 구성은 와일드카드 패턴 일치를 지원하지 않으며 프로토콜, 포트 또는 경로를 제한할 수 없습니다.

다음은 next.config.js 파일의 domains 속성 예시입니다.

module.exports = {
  images: {
    domains: ['assets.acme.com'],
  },
}

로더 구성

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}`
}

대신에 loader 속성을 사용하여 각 next/image 인스턴스를 구성할 수 있습니다.

예:

고급

다음 구성은 고급 사용 사례를 위한 것으로 일반적으로 필요하지 않습니다. 아래의 속성을 구성하면 Next.js 기본값을 덮어쓰게 됩니다.

디바이스 크기

사용자의 기대하는 디바이스 너비를 알고 있다면, next.config.js에서 deviceSizes 속성을 사용하여 디바이스 너비의 목록을 지정할 수 있습니다. 이러한 너비는 next/image 컴포넌트가 sizes prop을 사용할 때 사용되어 사용자의 디바이스에 맞는 올바른 이미지가 제공됩니다.

만약 구성이 제공되지 않은 경우, 아래의 기본값이 사용됩니다.

module.exports = {
  images: {
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
  },
}

이미지 크기

next.config.js 파일에서 images.imageSizes 속성을 사용하여 이미지 너비 목록을 지정할 수 있습니다. 이러한 너비는 디바이스 크기 배열과 연결되어 이미지 srcset을 생성하는 데 사용됩니다.

두 가지 별도의 목록이 있는 이유는 imageSizessizes prop을 제공하는 이미지에서만 사용되기 때문입니다. 이 prop은 이미지가 화면의 전체 너비보다 작은 것을 나타냅니다. 따라서 imageSizes에서의 크기는 deviceSizes에서 가장 작은 크기보다 모두 작아야 합니다.

만약 구성이 제공되지 않은 경우, 아래의 기본값이 사용됩니다.

module.exports = {
  images: {
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
}

허용 가능한 포맷

기본 Image Optimization API는 요청의 Accept 헤더를 통해 브라우저가 지원하는 이미지 포맷을 자동으로 감지합니다.

만약 Accept 헤더가 구성된 포맷 중 여러 개와 일치하는 경우, 배열에서 첫 번째 일치하는 포맷이 사용됩니다. 따라서 배열의 순서가 중요합니다. 일치하는 포맷이 없거나(또는 소스 이미지가 애니메이션인 경우) Image Optimization API는 원래 이미지의 포맷으로 대체됩니다.

만약 구성이 제공되지 않은 경우, 아래의 기본값이 사용됩니다.

module.exports = {
  images: {
    formats: ['image/webp'],
  },
}

다음 구성을 사용하여 AVIF 지원을 활성화할 수 있습니다.

module.exports = {
  images: {
    formats: ['image/avif', 'image/webp'],
  },
}

참고: AVIF는 보통 웹피(webp)보다 인코딩하는 데 20% 더 오래 걸리지만, 20% 더 작게 압축됩니다. 따라서 처음 이미지가 요청될 때 일반적으로 더 느릴 수 있지만 이후 캐시된 요청은 더 빠를 수 있습니다.

참고: Next.js 앞에 Proxy/CDN을 사용하는 경우 Accept 헤더를 전달하도록 구성해야 합니다.

캐싱 동작

기본 로더의 캐싱 알고리즘에 대해 설명합니다. 다른 로더의 경우, 클라우드 제공업체의 문서를 참조하세요.

이미지는 요청 시 동적으로 최적화되고 <distDir>/cache/images 디렉토리에 저장됩니다. 최적화된 이미지 파일은 만료 기간이 도래할 때까지 후속 요청에 대해 제공됩니다. 캐시된 만료된 파일과 일치하는 요청이 발생하면, 만료된 이미지가 즉시 불러와지고, 이미지는 다시 최적화되고 새로운 만료 날짜로 캐시에 저장됩니다.

이미지의 캐시 상태는 x-nextjs-cache 응답 헤더의 값을 읽어 확인할 수 있습니다. 가능한 값은 다음과 같습니다.

  • MISS - 경로가 캐시에 없습니다(첫 방문 때 최대 한 번 발생)
  • STALE - 경로가 캐시에 있지만 재확인 시간을 초과했으므로 백그라운드에서 업데이트됩니다.
  • HIT - 경로가 캐시에 있으며 재확인 시간을 초과하지 않았습니다.
    만료(또는 최대 Age)는 minimumCacheTTL 구성 또는 상위 이미지 Cache-Control 헤더 중 더 큰 값을 사용하여 정의됩니다. 구체적으로, Cache-Control 헤더의 max-age 값이 사용됩니다. s-maxagemax-age 모두를 찾은 경우 s-maxage가 우선합니다. max-ageCDN과 브라우저를 포함한 하위 클라이언트로 전달됩니다.

upstream 이미지에 Cache-Control 헤더가 없거나 값이 매우 낮은 경우 minimumCacheTTL을 구성하여 캐시 기간을 늘릴 수 있습니다.
deviceSizesimageSizes를 구성하여 생성 가능한 전체 이미지 수를 줄일 수 있습니다.
formats를 구성하여 하나의 이미지 형식을 선호하여 여러 형식을 사용하지 않도록 설정할 수 있습니다.

최소 캐시 TTL

최적화된 이미지의 캐시 수명을 초 단위로 구성할 수 있습니다. 대부분의 경우 정적 이미지 가져오기(Static Image Import)를 사용하는 것이 좋습니다. 이 경우 파일 내용을 자동으로 해싱하고 불변성 캐시 제어 헤더(Cache-Control header)로 이미지를 영구적으로 캐시합니다.

module.exports = {
  images: {
    minimumCacheTTL: 60,
  },
}

최적화된 이미지의 만료(혹은 최대 나이)는 upstream 이미지 Cache-Control 헤더와 minimumCacheTTL 중 큰 값으로 결정됩니다.

이미지별로 캐싱 동작을 변경해야 하는 경우, upstream 이미지에 Cache-Control 헤더를 설정할 수 있는 headers를 구성할 수 있습니다 (예: /some-asset.jpg, /_next/image 자체가 아님).

현재 캐시를 무효화하는 매커니즘이 없으므로, minimumCacheTTL을 낮게 유지하는 것이 좋습니다. 그렇지 않으면 src 속성을 수동으로 변경하거나 <distDir>/cache/images를 삭제해야 할 수 있습니다.

정적 이미지 가져오기 비활성화
기본 동작은 import icon from './icon.png'과 같은 정적 파일을 가져온 다음 해당 파일을 src 속성으로 전달하는 것입니다.

다른 플러그인과 충돌할 경우 이 기능을 비활성화하려면 next.config.js에서 정적 이미지 가져오기를 비활성화할 수 있습니다.

module.exports = {
  images: {
    disableStaticImages: true,
  },
}

위험한 SVG 허용

기본 로더는 몇 가지 이유로 SVG 이미지를 최적화하지 않습니다. 첫째, SVG는 벡터 형식이므로 손실 없이 크기를 조정할 수 있습니다. 둘째, SVGHTML/CSS와 많은 기능을 공유하기 때문에 적절한 콘텐츠 보안 정책(CSP) 헤더가 없으면 취약점을 유발할 수 있습니다.

기본 Image Optimization APISVG 이미지를 제공해야 하는 경우, next.config.js에서 dangerouslyAllowSVG를 설정할 수 있습니다.

module.exports = {
  images: {
    dangerouslyAllowSVG: true,
    contentDispositionType: 'attachment',
    contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
  },
}

또한, 브라우저가 이미지를 다운로드하도록 contentDispositionType을 강제로 설정하고, 이미지에 포함된 스크립트 실행을 방지하기 위해 contentSecurityPolicy를 설정하는 것이 강력하게 권장됩니다.

애니메이션 이미지

기본 로더는 애니메이션 이미지에 대해서는 자동으로 Image Optimization을 우회하고 그대로 이미지를 제공합니다.

애니메이션 파일의 자동 감지는 최선을 다하며 GIF, APNGWebP를 지원합니다. 특정 애니메이션 이미지에서 Image Optimization을 명시적으로 우회하려면 unoptimized 프롭을 사용하세요.

0개의 댓글