[ Optimizing ] Images

차차·2023년 5월 23일
0

Next Docs

목록 보기
25/34
post-thumbnail

Next.js의 Image 컴포넌트는 HTML <img> 요소를 확장하여 다음과 같은 기능을 제공한다.

  1. 크기 최적화

    WebP 및 AVIF와 같은 현대적인 이미지 형식을 사용하여 각 장치에 맞게 올바르게 크기 조정된 이미지를 자동으로 제공한다.

  2. 시각적 안정성
    이미지가 로드될 때 자동으로 레이아웃 이동을 방지한다.

  3. 빠른 페이지 로딩
    이미지는 웹 브라우저의 네이티브 지연 로딩을 사용하여 뷰포트에 진입할 때만 로드되며, 선택적으로 흐릿한 플레이스홀더를 사용할 수 있다.

  4. 자산 유연성
    원격 서버에 저장된 이미지를 포함하여 필요에 따라 이미지 크기를 실시간으로 조정할 수 있다.



사용법

import Image from 'next/image';

로컬 이미지(Local Images)

로컬 이미지를 사용하려면 .jpg, .png 또는 .webp 이미지 파일을 가져와야 한다.

Next.js는 가져온 파일을 기반으로 이미지의 너비와 높이를 자동으로 결정한다. 이 값은 이미지가 로드되는 동안 누적 레이아웃 변화(Cumulative Layout Shift)를 방지하는 데 사용된다.

// 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} automatically provided
      // height={500} automatically provided
      // blurDataURL="data:..." automatically provided
      // placeholder="blur" // Optional blur-up while loading
    />
  );
}

동적인 await import() 또는 require()은 지원되지 않는다. import는 정적이어야 하므로 빌드 시간에 분석할 수 있어야 한다.


원격 이미지(Remote Images)

원격 이미지를 사용하려면 src 속성에 URL 문자열을 제공해야 한다.

Next.js는 빌드 과정에서 원격 파일에 액세스할 수 없으므로 width, height 및 선택적인 blurDataURL 속성을 수동으로 제공해야 한다.

너비높이 속성은 이미지의 올바른 종횡비를 추론하고 이미지 로딩으로 인한 레이아웃 변화를 방지하는 데 사용된다. 너비와 높이는 이미지 파일의 렌더링 크기를 결정하지는 않는다.

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/**',
      },
    ],
  },
};

이미지 src에 상대적인 URL을 사용하려면 로더(loader)를 사용한다.


도메인(Domains)

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

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


Loaders

앞서 언급한 예제에서 원격 이미지에 대해 부분 URL("/me.png")이 제공되었다. 이는 로더 아키텍처 덕분에 가능한 것이다.

로더는 이미지의 URL을 생성하는 함수다. 이는 제공된 src를 수정하고 다른 크기로 이미지를 요청하기 위해 여러 URL을 생성한다. 이러한 여러 URL은 자동으로 srcset을 생성하는 데 사용되어 방문자가 뷰포트에 적합한 크기의 이미지를 제공받을 수 있다.

Next.js 애플리케이션의 기본 로더는 내장된 이미지 최적화 API를 사용하여 웹의 어느 곳에서나 이미지를 최적화한 다음 Next.js 웹 서버에서 직접 제공한다. CDN이나 이미지 서버에서 이미지를 직접 제공하고 싶다면 몇 줄의 JavaScript로 고유한 로더 함수를 작성할 수 있다.

loader prop으로 이미지당 로더를 정의하거나 loaderFile configuration을 사용하여 애플리케이션 수준에서 로더를 정의할 수 있다.



우선 순위(priority)

각 페이지의 가장 큰 콘텐츠가 되는 이미지에 priority 속성을 추가해야 한다. 이렇게 함으로써 Next.js는 이미지를 로딩하기 위해 특별한 우선순위(예: preload 태그 또는 우선순위 힌트)를 부여할 수 있으며, LCP(Largest Contentful Paint)에 의미 있는 향상을 가져올 수 있다.

LCP 요소는 일반적으로 페이지의 뷰포트 내에서 가장 큰 이미지 또는 텍스트 블록이다. next dev를 실행할 때 LCP 요소가 priority 속성이 없는 <Image>인 경우 콘솔 경고가 표시된다.

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

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 />;
}


이미지 사이징(Image Sizing)

이미지가 성능에 가장 많은 영향을 주는 방법 중 하나는 이미지가 로드되는 동안 페이지에서 다른 요소들을 밀어내어 레이아웃이 변경되는 레이아웃 시프트(layout shift)다. 이러한 성능 문제는 사용자에게 귀찮음을 야기하여 Cumulative Layout Shift라는 자체적인 Core Web Vital을 가지게 되었다. 이미지 기반 레이아웃 시프트를 피하기 위해서는 항상 이미지의 크기를 지정해야 한다. 이렇게 함으로써 브라우저는 이미지가 로드되기 전에 정확히 충분한 공간을 예약할 수 있다.


next/image는 좋은 성능 결과를 보장하기 위해 설계되었으므로 레이아웃 시프트에 기여하지 않을 수 있는 방식으로 사용해야 하며, 다음 중 하나의 방식으로 크기를 지정해야 한다.

  1. 정적 임포트를 사용하여 자동으로 크기를 결정한다.

  2. widthheight 속성을 사용하여 명시적으로 크기를 지정한다.

  3. fill을 사용하여 부모 요소에 맞추어 이미지 크기를 암시적으로 지정한다. 이렇게 함으로써 이미지는 부모 요소를 채우도록 확장된다.


💡  이미지 크기를 모르는 경우

이미지의 크기를 알지 못하는 소스에서 이미지에 접근하는 경우 다음과 같은 방법이 있다.

  1. fill 사용
    fill 속성을 사용하면 이미지가 부모 요소에 따라 크기가 결정된다. CSS를 사용하여 이미지의 부모 요소에 페이지에서 공간을 제공하고 sizes 속성을 사용하여 미디어 쿼리 브레이크 포인트와 일치하도록 할 수 있다. 또한 fill, contain 또는 coverobject-position을 함께 사용하여 이미지가 해당 공간을 어떻게 차지할지 정의할 수 있다.

  2. 이미지 정규화
    제어 가능한 소스에서 이미지를 제공하는 경우 이미지를 특정 크기로 정규화하기 위해 이미지 파이프라인을 수정하는 것을 고려한다.

  3. API 호출 수정
    애플리케이션이 이미지 URL을 API 호출을 통해 가져오는 경우 (예: CMS로부터), API 호출을 수정하여 URL과 함께 이미지의 크기를 반환할 수 있다.


이미지 크기 조정에 대한 제안된 방법이 모두 작동하지 않는 경우 next/image 컴포넌트는 표준 <img> 요소와 함께 페이지에서 잘 작동하도록 설계되었다.



스타일링(Styling)

Image 컴포넌트의 스타일링은 일반 <img> 요소의 스타일링과 유사하지만 몇 가지 지침을 염두에 두어야 한다.

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


구성(Configuration)

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



[ 출처 ]
https://nextjs.org/docs/app/building-your-application/optimizing/images

profile
나는야 프린이

0개의 댓글