data life

[Next.js] Next.js에서 이미지 태그를 안쓰는 이유 본문

Front-end

[Next.js] Next.js에서 이미지 태그를 안쓰는 이유

주술회전목마 2023. 12. 5. 17:29

 

 

 

 

 


Next.js에서 img 태그 사용 시, 다음과 같은 문구를 보신 적이 있으실 겁니다.

Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` to automatically optimize images. This may incur additional usage or cost from your provider.

 

📌 Image Component & Image Optimization

Next.js에서는 이미지를 자동으로 최적화시켜 주어 따로 처리해주지 않아도 되도록 해줍니다.

이미지 컴포넌트인 `next/image`는 모던 웹용으로 발전된 HTML img 태그의 확장입니다. 해당에는 우수한 Core Web Vitals를 달성하는 데 도움되는 다양한 기본 성능 최적화가 포함되어 있습니다. 

LCP 콘텐츠 유형

즉, <img> 대신에 Next.js의 image component로 이미지를 사용하는 것을 권고합니다.

 

 

📌 대표 기능

 

1. Lazy loading

이미지 로드하는 시점을 필요로 할 때까지 지연시키는 기술입니다. 즉, 사용자가 이미지가 나올 때까지 스크롤을 하지 않으면 이미지를 로드하지 않습니다.

해당 페이지를 계속 내리다보면 더 많은 이미지들과 글들을 볼 수 있는데 Next.js가 해당 페이지를 더 빠르게 로드하기 위해서는 모든 이미지들을 불러올 필요가 없겠죠? 사용자가 스크롤하는 만큼만 이미지를 다운로드하므로써 불필요한 대역폭 사용을 줄이고 웹 사이트의 성능을 향상시킬 수 있습니다.

 

기존 lazy loading을 구현하기 위해서는 Intersection Observer 혹은 scroll event를 통해 해당 스크롤 시, 스크린의 위치를 캐치하여 이미지를 로드하도록 구현하였으나 next.js에서는 자동으로 lazy loading이 적용되기 때문에 굉장히 편리합니다.

 

2. Preloading(placeholder 제공)

보여줄 로고 이미지나 미리 정의된 이미지와 같은 local image가 있을 경우, 해당 이미지에 대한 placeholder를 만듭니다.

placeholder는 저해상도의 이미지로, 로드하기 쉬운 방식입니다.

 

Next.js가 기본으로 제공하는 이미지 최적화를 통해 우리는 두 가지 버전의 이미지를 만들 필요가 없게 됩니다.

위와 같이 해당 이미지들을 흐린 이미지로 만들어 주기 때문이죠! 👏👏

사용자가 아무것도 볼 수 없는 것 대신에 해당 위치에 어떠한 이미지가 존재하는 지 어느정도 사전에 예기하여 주기 때문에 사용자 경험도 높아질 수 있습니다. 이를 CLS(Cumulative Layout Shift)라고 부르며 레이아웃이 흔들리는 현상을 방지하기 위함으로 next.js에서는 placeholder를 제공하고 있습니다.

 

3. 이미지 사이즈 최적화

Next.js는 디바이스의 크기 별로 srcSet을 미리 지정해두어 사용자의 디바이스에 맞는 이미지를 다운로드하도록 지원해줍니다.

 

 

📌 Local Image vs Remote Image

 

- local Image(로컬 이미지) 란

파일 시스템에 있는 이미지를 말하며 api 응답에 의존하지 않는 이미지

=> 사용자가 페이지에 도착하기도 전에 이미 이미지를 인식할 수 있어서 최적화에 용이합니다.

 

- remote image(원격 이미지) 란

해당 이미지의 src가 무엇인지 url이 무엇인지 알기 위해 api 응답을 기다려야 하는 이미지

=> 따라서, 이미지를 받을 때까지 기다려야하기 때문에 local image만큼 최적화는 되지 않습니다.

그래서 앞서 소개한 흐릿한 이미지는 remote image에 적용할 수 없게 됩니다. 

 

 

📌 How to Use

 

- local Image(로컬 이미지)

1. next/image import

import Image from 'next/image'

 

2. 해당 이미지 import

import profilePic from '../public/me.png'

 

next.js는 가져온 파일을 기반으로 이미지를 자동으로 결정합니다.

 

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

 

next.js가 자동적으로 width와 height 및 스타일을 적용해주고 url을 생성해준 것을 확인할 수 있습니다.

 

만일 블러효과를 주고 싶다면 placeholder="blur"를 추가해주면 됩니다.

그 외에도 품질을 변경하고 싶다면 quality={num}를 변경해주면 됩니다.

 

 

- remote image(원격 이미지)

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

이미지 최적화를 안전하게 허용하기 위해서는 아래와 예시와 같이 next.config.js에서 지원되는 URL 패턴 목록을 정의해주어야 합니다. 

module.exports = {
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 's3.amazonaws.com',
        port: '',
        pathname: '/my-bucket/**',
      },
    ],
    domains: ['cloud.com'],
    loader: 'imgix',
    path: 'https://example.com/myaccount/',
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
    imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
  },
}

이외에도 formats(지원 이미지 포맷), minimumCacheTTL(캐싱 이미지 수명), disableStaticImage(정적 이미지 비활성화), dangerouslyAllowSVG(svg 포맷 지원) 등의 옵션을 설정할 수 있다.

 

아래와 같은 에러가 발생하는데 이러한 에러가 발생한 이유는 remote image는 해당 파일의 정보를 미리 접근할 수 없기 때문에 width, height props를 필수로 입력해줘야하기 때문입니다.

 

<Image> 컴포넌트의 필수 / 옵션 속성 값들은 다음과 같습니다.

<Image

  // 필수 Props
  src="https://cdn.com/image.webp"
  alt="next image"
  width={40}
  height={40}
  
  // 옵션 Props
  layout="responsive"
  loader={exampleLoader}
  sizes="320 640 750"
  quality={100}
  priority
  placeholder="blur"
  blurDataUrl="../public/blur.jpg"
  
  // Advanced Props
  objectFit="contain"
  objectPosition="top right"
  loading="lazy"
  onLoadingComplete={(imageDimension} => console.log(imageDimension)}
  lazyBoundary="200px"
  unoptimized
/>

 

 

📌 정리

Next/image의 장점들을 살펴보며 아래 정리와 함께 글을 마무리하도록 하겠습니다.

- 성능 향상 : 디바이스마다 적절한 사이즈의 이미지를 제공해주고
시각적 안정성 향상 : 이미지가 로드되기 전에 흐린이미지를 제공하므로써 CLS를 방지해줍니다.
빠른 로딩 속도 : viewport에 들어왔을 때에만 이미지를 로드하여 더 빠른 페이지를 보여줄 수 있게 됩니다.

 

 

 

📖 참고 문헌

공식문서

https://almanac.httparchive.org/en/2022/performance#introduction

https://fe-developers.kakaoent.com/2022/220714-next-image/

'Front-end' 카테고리의 다른 글

[Next.js] Next.js에 대해 알아보자  (0) 2023.11.03