Next.js에서는 Image 컴포넌트를 따로 제공한다.
어떠한 기능들을 제공하길래 next/image를 사용하면 좋다는 것일까?
Next 15 기준으로 설명을 진행해보려고 한다.
실제 html의 <img>를 래핑하여 같은 URL이면 값을 캐싱해서 보여준다.
위의 경우는 프론트엔드 자체 리소스가 아닌(public/에 존재하지 않는) 이미지의 경우 해당 이미지를 다운로드 받아서 .next/cache/images에 저장하게 된다.

이렇게 외부 CDN에 저장된 이미지를 src에 넣게되면 Next.js는 자체적으로 webp 형태의 이미지로 캐싱을 하게 된다.

참고로 webp 형식은 무손실 압축인 png 보다도 압축률이 뛰어나기에 next.js에서 채택한 방식이다. 구글에서 만든 웹전용 이미지 압축방식이다.

원본 이미지는 750 x 750 이었는데 캐싱된 webp 또한 무손실로 변환되었으며 크기는 200kb 에서 100kb로 2배가량 이득을 보았다.
필자가 테스트를 위해 같은 링크의 <Image> 컴포넌트를 10개 생성했는데, 총 1개의 캐시 이미지가 생성되었다.
같은 src 인 경우 하나의 캐시를 공유하여 최적화 하는것으로 보인다.
<img>에는 lazy loading이라는 것이 있는데, 처음부터 이미지를 로딩하는 것이 아니라, 화면에 들어왔을 때 로딩하는 기능이 있다.
자세한 글은 아래를 참고바란다.
웹 성능 최적화를 위한 Image Lazy Loading 기법
next/image는 따로 loading='lazy'를 주지 않아도 자동으로 속성을 부여한다.
이를 없애고 싶으면 loading='eager'(브라우저가 즉시로드), prioirty(Next.js 에서 최적화한 이미지를 즉시로드)를 사용하면 된다.
원본 이미지는 1920 x 1080 픽셀일 수도, 750 x 750 픽셀일 수도 있다.
Next.js에서는 해당 이미지를 링크로만 받기때문에 페칭하기 전에는 이미지의 크기를 알지 못한다.
그래서 width, height 속성을 미리 주어서 원본 이미지의 크기를 미리 알려주어야한다.
<Image
src="/static/image.jpg"
width={1920}
height={1080}
alt="Static Image"
/>
정적이미지(/public 에 저장하는 이미지)인 경우는 미리 이미지의 크기를 알 수 있기 때문에 해당 속성을 사용하지만, 동적이미지(게시글 썸네일, 상품 이미지 등)는 이미지의 원본비율이 제각각이기 때문에 fill 속성을 사용할 수 있다.
<div className="relative w-full h-64">
<Image
src="https://example.com/image.jpg"
alt="Dynamic Image"
fill
className="object-cover rounded-lg"
/>
</div>
fill 속성을 사용하면 부모 요소의 크기에 맞게 이미지를 자동으로 조정한다. 이때 부모 요소에 relative 클래스를 설정해야 한다.
next/image는 이미지 품질을 설정할 수 있는 quality 속성을 제공한다. 이 속성은 이미지 최적화에서 품질과 파일 크기 사이의 균형을 맞출 수 있게 도와준다. quality 값은 1부터 100까지 설정할 수 있으며, 100이 가장 높은 품질을 의미한다.
<Image
src="https://example.com/image.jpg"
width={750}
height={750}
alt="Optimized Image"
quality={80} // 80% 품질로 최적화
/>
외부에 존재하는 이미지더라도 캐싱을 통해 next 서버 자체에 이미지를 저장하게 되므로, quality를 사용해서 이미지의 품질을 커스터마이즈할 수 있다.
next/image를 사용하면 다음과 같은 장점이 있다:
✅ 이미지 자동 최적화 (WebP 변환 & 캐싱 지원)
✅ Lazy Loading 기본 제공 (성능 최적화)
✅ 반응형 이미지 지원 (fill 속성 활용)
✅ 중복 요청 방지 (같은 src는 하나의 캐시를 공유)
✅ 이미지 품질 최적화 (quality 속성)
Next.js에서 이미지 최적화는 필수적인 성능 개선 요소이므로, 가능하면 <img> 태그 대신 next/image를 사용하는 것이 좋다.
하지만 next/image를 사용하지 않아도 되는 경우가 있다:
❎ 이미지 최적화가 불필요한 경우: 이미 외부 CDN이나 서비스에서 최적화된 이미지를 사용하는 경우.
❎ 정적 이미지(고정된 크기): 크기가 고정된 이미지들에 대해 최적화가 필요 없는 경우.
❎ 프로그레시브 이미지 사용: 프로그래시브 JPEG 등 이미지를 사용하고 있어 추가적인 최적화가 불필요한 경우.
❎ 작은 이미지: 아이콘, 작은 로고 등 최적화 효과가 미미한 작은 이미지인 경우.
❎ 동적 처리나 효과가 필요한 이미지: 복잡한 동적 처리나 JavaScript 효과를 적용해야 하는 경우.
왜냐하면 next/image 자체의 최적화 로직은 복잡하기 때문이다.
앞에 말한 장점들을 모두 지원하기 때문에 방대한 로직들을 img 를 위해 실행한다. 경우를 잘 고려하여 이미지 최적화를 하는 것이 중요하다.