문서
App Router 사용하기
Images

이미지 최적화

예제

Web Almanac에 따르면, 이미지는 일반적인 웹사이트의 페이지 용량 중 큰 부분을 차지하며 웹사이트의 LCP 성능에 상당한 영향을 미칠 수 있습니다.

Next.js Image 컴포넌트는 HTML <img> 요소를 확장하여 자동 이미지 최적화 기능을 제공합니다:

  • 크기 최적화: 각 기기에 맞는 크기의 이미지를 WebP와 AVIF 같은 현대적인 이미지 형식으로 자동 제공합니다.
  • 시각적 안정성: 이미지 로딩 시 레이아웃 이동을 자동으로 방지합니다.
  • 빠른 페이지 로드: 이미지는 브라우저의 기본 지연 로딩을 사용하여 뷰포트에 들어올 때만 로드되며, 선택적으로 blur-up 플레이스홀더를 사용할 수 있습니다.
  • 자산 유연성: 원격 서버에 저장된 이미지도 온디맨드로 크기를 조정할 수 있습니다.

🎥 시청하기: next/image 사용 방법에 대해 자세히 알아보기 → YouTube (9분).

사용법

import Image from "next/image";

그런 다음 이미지의 src를 정의할 수 있습니다(로컬 또는 원격).

로컬 이미지

로컬 이미지를 사용하려면 .jpg, .png, 또는 .webp 이미지 파일을 import하세요.

Next.js는 가져온 파일을 기반으로 이미지의 본질적인 widthheight자동으로 결정합니다. 이 값들은 이미지 비율을 결정하고 이미지 로딩 중 누적 레이아웃 이동을 방지하는 데 사용됩니다.

app/page.js
import Image from "next/image";
import profilePic from "./me.png";
 
export default function Page() {
  return (
    <Image
      src={profilePic}
      alt="Picture of the author"
      // width={500} 자동으로 제공됨
      // height={500} 자동으로 제공됨
      // blurDataURL="data:..." 자동으로 제공됨
      // placeholder="blur" // 로딩 중 선택적 블러 처리
    />
  );
}

경고: 동적 await import() 또는 require()지원되지 않습니다. import는 빌드 시 분석할 수 있도록 정적이어야 합니다.

원격 이미지

원격 이미지를 사용하려면 src 속성이 URL 문자열이어야 합니다.

Next.js는 빌드 과정에서 원격 파일에 접근할 수 없기 때문에, width, height 및 선택적 blurDataURL 속성을 수동으로 제공해야 합니다.

widthheight 속성은 이미지의 올바른 종횡비를 추론하고 이미지 로딩으로 인한 레이아웃 이동을 피하는 데 사용됩니다. widthheight는 이미지 파일의 렌더링 크기를 결정하지 않습니다. 이미지 크기 조정에 대해 자세히 알아보세요.

app/page.js
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}
    />
  );
}

이미지를 안전하게 최적화할 수 있도록 next.config.js에서 지원되는 URL 패턴 목록을 정의하세요. 악의적인 사용을 방지하기 위해 가능한 한 구체적으로 정의하세요. 예를 들어, 다음 구성은 특정 AWS S3 버킷의 이미지만 허용합니다:

next.config.js
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "s3.amazonaws.com",
        port: "",
        pathname: "/my-bucket/**",
      },
    ],
  },
};

remotePatterns 구성에 대해 자세히 알아보세요. 이미지 src에 상대 URL을 사용하려면 loader를 사용하세요.

도메인

때로는 원격 이미지를 최적화하면서도 내장된 Next.js 이미지 최적화 API를 사용하고 싶을 수 있습니다. 이를 위해 loader를 기본 설정으로 두고 Image src 속성에 절대 URL을 입력하세요.

악의적인 사용자로부터 애플리케이션을 보호하기 위해 next/image 컴포넌트와 함께 사용하려는 원격 호스트네임 목록을 정의해야 합니다.

remotePatterns 구성에 대해 자세히 알아보세요.

로더

이전 예제에서 로컬 이미지에 대해 부분 URL("/me.png")이 제공된 것을 주목하세요. 이는 로더 아키텍처 때문에 가능합니다.

로더는 이미지의 URL을 생성하는 함수입니다. 제공된 src를 수정하고 다양한 크기로 이미지를 요청하기 위한 여러 URL을 생성합니다. 이 여러 URL은 자동 srcset 생성에 사용되어 사이트 방문자에게 뷰포트 크기에 맞는 이미지를 제공합니다.

Next.js 애플리케이션의 기본 로더는 내장된 이미지 최적화 API를 사용하며, 이는 웹 어디에서나 이미지를 최적화하고 Next.js 웹 서버에서 직접 제공합니다. CDN이나 이미지 서버에서 직접 이미지를 제공하려면 몇 줄의 JavaScript로 자체 로더 함수를 작성할 수 있습니다.

loader 속성을 사용하여 이미지별로 로더를 정의하거나 loaderFile 구성을 사용하여 애플리케이션 수준에서 로더를 정의할 수 있습니다.

우선순위

각 페이지의 최대 콘텐츠풀 페인트(LCP) 요소가 될 이미지에 priority 속성을 추가해야 합니다. 이를 통해 Next.js가 이미지 로딩을 특별히 우선시할 수 있어(예: 프리로드 태그나 우선순위 힌트를 통해) LCP에 의미 있는 향상을 가져올 수 있습니다.

LCP 요소는 일반적으로 페이지의 뷰포트 내에서 볼 수 있는 가장 큰 이미지나 텍스트 블록입니다. next dev를 실행하면 priority 속성이 없는 <Image>가 LCP 요소인 경우 콘솔 경고가 표시됩니다.

LCP 이미지를 식별한 후에는 다음과 같이 속성을 추가할 수 있습니다:

app/page.js
import Image from "next/image";
import profilePic from "../public/me.png";
 
export default function Page() {
  return <Image src={profilePic} alt="Picture of the author" priority />;
}

우선순위에 대한 자세한 내용은 next/image 컴포넌트 문서를 참조하세요.

이미지 크기 조정

이미지가 성능을 해치는 가장 일반적인 방법 중 하나는 레이아웃 이동입니다. 이미지가 로드되면서 페이지의 다른 요소들을 밀어내는 현상입니다. 이 성능 문제는 사용자에게 너무 성가신 나머지 누적 레이아웃 이동이라는 자체 Core Web Vital을 가지고 있습니다. 이미지 기반 레이아웃 이동을 피하는 방법은 항상 이미지 크기를 지정하는 것입니다. 이를 통해 브라우저는 이미지가 로드되기 전에 정확히 필요한 공간을 예약할 수 있습니다.

next/image는 좋은 성능 결과를 보장하도록 설계되었기 때문에 레이아웃 이동에 기여할 수 있는 방식으로 사용할 수 없으며, 다음 세 가지 방법 중 하나로 반드시 크기가 지정되어야 합니다:

  1. 정적 가져오기를 사용한 자동 크기 지정
  2. 이미지의 종횡비를 결정하는 데 사용되는 widthheight 속성을 수동으로 포함
  3. fill을 사용하여 이미지가 부모 요소를 채우도록 하는 암시적 방법

이미지 크기를 모르는 경우에는 어떻게 해야 하나요?

이미지 크기를 알 수 없는 소스에서 이미지에 접근하는 경우 다음과 같은 방법을 사용할 수 있습니다:

fill 사용하기

fill 속성을 사용하면 이미지가 부모 요소의 크기에 맞춰집니다. CSS를 사용하여 이미지의 부모 요소에 공간을 주고 sizes 속성을 사용하여 미디어 쿼리 브레이크포인트와 일치시키는 것을 고려하세요. 또한 fill, contain, 또는 cover와 함께 object-fit을 사용하고, object-position을 사용하여 이미지가 그 공간을 어떻게 차지해야 하는지 정의할 수 있습니다.

이미지 정규화하기

제어할 수 있는 소스에서 이미지를 제공하는 경우, 이미지 파이프라인을 수정하여 이미지를 특정 크기로 정규화하는 것을 고려해보세요.

API 호출 수정하기

애플리케이션이 API 호출을 사용하여 이미지 URL을 검색하는 경우(예: CMS에서), API 호출을 수정하여 URL과 함께 이미지 치수를 반환하도록 할 수 있습니다.

제안된 방법 중 어느 것도 이미지 크기 조정에 적합하지 않다면, next/image 컴포넌트는 표준 <img> 요소와 함께 페이지에서 잘 작동하도록 설계되었습니다.

스타일링

Image 컴포넌트의 스타일링은 일반 <img> 요소의 스타일링과 유사하지만 몇 가지 주의해야 할 가이드라인이 있습니다:

  • className 또는 style을 사용하고, styled-jsx는 사용하지 마세요.
    • 대부분의 경우 className 속성을 사용하는 것을 권장합니다. 이는 가져온 CSS 모듈, 전역 스타일시트 등이 될 수 있습니다.
    • style 속성을 사용하여 인라인 스타일을 지정할 수도 있습니다.
    • styled-jsx는 현재 컴포넌트에 범위가 지정되어 있기 때문에 사용할 수 없습니다(스타일을 global로 표시하지 않는 한).
  • fill을 사용할 때 부모 요소는 position: relative를 가져야 합니다.
    • 이는 해당 레이아웃 모드에서 이미지 요소를 올바르게 렌더링하는 데 필요합니다.
  • fill을 사용할 때 부모 요소는 display: block을 가져야 합니다.
    • 이는 <div> 요소의 기본값이지만 그렇지 않은 경우 지정해야 합니다.

예제

반응형

부모 컨테이너의 너비와 높이를 채우는 반응형 이미지
import Image from "next/image";
import mountains from "../public/mountains.jpg";
 
export default function Responsive() {
  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      <Image
        alt="Mountains"
        // 이미지를 가져오면
        // 자동으로 너비와 높이가 설정됩니다
        src={mountains}
        sizes="100vw"
        // 이미지를 전체 너비로 표시
        style={{
          width: "100%",
          height: "auto",
        }}
      />
    </div>
  );
}

컨테이너 채우기

부모 컨테이너 너비를 채우는 이미지 그리드
import Image from "next/image";
import mountains from "../public/mountains.jpg";
 
export default function Fill() {
  return (
    <div
      style={{
        display: "grid",
        gridGap: "8px",
        gridTemplateColumns: "repeat(auto-fit, minmax(400px, auto))",
      }}
    >
      <div style={{ position: "relative", height: "400px" }}>
        <Image
          alt="Mountains"
          src={mountains}
          fill
          sizes="(min-width: 808px) 50vw, 100vw"
          style={{
            objectFit: "cover", // cover, contain, none
          }}
        />
      </div>
      {/* 그리드에 더 많은 이미지... */}
    </div>
  );
}

배경 이미지

페이지의 전체 너비와 높이를 차지하는 배경 이미지
import Image from "next/image";
import mountains from "../public/mountains.jpg";
 
export default function Background() {
  return (
    <Image
      alt="Mountains"
      src={mountains}
      placeholder="blur"
      quality={100}
      fill
      sizes="100vw"
      style={{
        objectFit: "cover",
      }}
    />
  );
}

다양한 스타일로 사용된 Image 컴포넌트의 예제는 Image 컴포넌트 데모를 참조하세요.

기타 속성

next/image 컴포넌트에 사용 가능한 모든 속성 보기.

구성

next/image 컴포넌트와 Next.js Image Optimization API는 next.config.js 파일에서 구성할 수 있습니다. 이러한 구성을 통해 원격 이미지 활성화, 사용자 정의 이미지 브레이크포인트 정의, 캐싱 동작 변경 등을 할 수 있습니다.

자세한 내용은 전체 이미지 구성 문서를 참조하세요.