Posts next/image 컴포넌트
Post
Cancel

next/image 컴포넌트

next.js에서는 next/image로 자체적인 이미지 컴포넌트를 제공한다. 일반적인 img 태그와는 달리 여러 성능 최적화기법이 내장되어있다. 기본적으로 다음과 같은 기능을 제공한다.

  • 성능 향상 : 각 디바이스에 정확히 맞는 이미지를 모던 웹 포맷에 맞게 제공한다.
  • Visual Stability : Cumulative Layout Shift를 자동으로 예방한다.
    • Cumulative Layout Shift : 웹 화면의 레이아웃이 갑자기 바뀌는 것. 사용자가 의도치않은 동작을 실행할 수 있다.
  • Faster Page Loads : 뷰포트 안에 들어와야만 이미지가 로드되게 한다. 선택적으로 블러처리된 placeholder를 둘 수 있다.
  • Asset Flexibility : 이미지가 리모트 서버에 저장되어있어도, on-demand image resizing을 지원한다.


nexy/Image 컴포넌트 사용법

컴포넌트 import

1
import Image from "next/image"

image 불러오기

  • Local Image

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    
    import profilePic from '../public/me.png'
      
    function Home() {
      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
          />
      )
    }
    
    • import문이 빌드시 분석되어야하기 때문에 Dynamic await import() 또는 require()는 지원되지 않는다.
  • width, height는 next.js에서 자동으로 계산한다. 이는 Cumulative Layout Shift를 방지하기 위해 쓰인다.
    • blurDataURL도 자동으로 지원된다.
  • Remote image

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    import Image from 'next/image'
      
    export default function Home() {
      return (
          <Image
            src="/me.png"
            alt="Picture of the author"
            width={500}
            height={500}
          />
      )
    }
    
    • 절대주소 또는 상대주소로 이미지의 위치를 명시한다. 이때 상대주소는 public 폴더 이하의 경로이다.
    • 빌드시 remote image에 접근하지 않기에,width, height를 명시해주어야한다.
    • blurDataURL 또한 직접 입력해야한다.


Loaders

Remote image를 불러오는 예제에서 src 값을 /me.png와 같은 상대경로로 입력하였는데, 이것이 가능한 이유는 Loader가 있기 때문이다.

loader는 이미지의 URL을 생성하는 함수이다. src를 변경하여 다양한 사이즈의 이미지를 요청하는 여러 URL을 생성한다. 이러한 여러 URL은 자동으로 srcset을 생성하고, 사이트에 방문한 유저가 적절한 사이즈의 이미지를 다운 받도록한다.

default loader는 이미지를 가져와 최적화한 다음에 next.js 웹 서버에서 제공한다. 만약 CDN이나 image server에서 직접 이미지를 가져가도록 하고 싶다면, 직접 loader 함수를 작성할 수 있다. next/image컴포넌트마다 loader 속성을 지정할 수 있으며, 아니면 어플리케이션 레벨로 next.config.js에서 loader를 지정할 수 있다.


Domains

remote image를 최적화하고 싶을 때, loader 는 디폴트 설정으로 두고, next/image 컴포넌트의 src 에는 절대경로를 입력한다. 악의적인 공격을 막기 위해 remote hostname을 반드시 정의해야한다. 다음과 같이 next.config.js에서 정의할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 'example.com',
        port: '',
        pathname: '/account123/**',
      },
      {
        protocol: 'https',
        hostname: '**.example.com',
      },
    ],
  },
}
  • 와일드카드 *hostnamepathname에 모두 쓰일 수 있다.
    • * : 하나의 path segment 또는 subdomain과 매칭된다.
    • ** ; 여러 path segment 또는 subdomain과 매칭된다.
      • www.**.com과 같이 중간 부분에서 적용되진 않는다.

좀 더 간단하게 domain만 명시할 수도 있다. 하지만 domain은 와일드카드를 지원하지 알고, protocol을 지정할 수 없기에 remotePatterns가 권장된다.

1
2
3
4
5
module.exports = {
  images: {
    domains: ['assets.acme.com'],
  },
}

remotePatterns에 관한 자세한 내용


Priority

priority속성을 사용하여 이미지 로딩에 우선순위를 둘 수 있다. LCP 엘리먼트에 쓰일 수 있으며, 이미지가 페이지에 접속하자마자 보여야할 때만 사용하는 것이 좋다,


Image Sizing

이미지가 퍼포먼스에 악영향을 미치는 가장 큰 요인은 cumulative layout shift이다 . 이미지가 늦게 로딩되어 다른 엘리먼트를 멀어내는 것을 말한다. 유저의 입장에선 매우 짜증나는 이슈이다.

이 이슈를 막기 위해서는 이미지의 사이즈를 기입해야한다. 이미지의 사이즈를 기업하면, 브라우저는 이미지가 로드되기 전에 이미지를 위한 공간을 미리 잡아둔다.

next/image에서는 다음 세가지 방법중 하나를 사용한다.

  1. static import를 통해 이미지를 가져오면 자동으로 계산한다.

  2. 명시적으로 width, height속성을 기입한다.

  3. fill 속성은 부모 요소를 채울 때 사용하며, 이 속성을 사용하면, width, height를 기입하지 않아도 자동으로 계산된다. 다만 부모 요소의 position이 relative, absolute, fixed 중 하나여야한다.

    fill 속성에 대해 자세히


Styling

기본적으로는 <img> 태그를 사용할 때와 같지만 아래 주의사항이 있다.

글로벌이 아닌 styled-jsx 대신에 className 또는 style을 사용한다.

styled-jsx는 글로벌로 사용하지 않는한 현재 컴포넌트에서만 적용되기에 사용할 수 없다.

fill 속성 사용시, 부모 요소는 position:relative여야한다.

적절한 사이즈를 계산하기 위해 필요하다.

fill 속성 사용시, 부모요소는 deplay: block여야한다.

<div> 엘리먼트일 경우엔 이미 적용되어있지만, 다른 엘리먼트라면 명시적으로 설정해야한다.


출처

next/image 가이드 : https://nextjs.org/docs/basic-features/image-optimization

next/image 레퍼런스 : https://nextjs.org/docs/api-reference/next/image

This post is licensed under CC BY 4.0 by the author.

container 안에서 pm2로 next.js 앱 실행하기

next.js - Automatic Static 최적화

Comments powered by Disqus.