이미지는 웹 페이지의 시각적 경험을 담당하지만, 동시에 가장 큰 리소스다. 특히 모바일 환경에서는 이미지로 인해 페이지 로딩 속도나 TTI(Time To Interactive)에 큰 영향을 미친다. Next.js는 이러한 문제를 해결하기 위해 next/image 컴포넌트를 중심으로 한 이미지 최적화 기능을 제공한다.
왜 이미지 최적화가 중요한가?
웹 페이지 리소스 크기 중 이미지가 차지하는 비중은 평균적으로 50% 이상이다.
최적화되지 않은 이미지는 FCP/LCP 지연, 데이터 요금 증가, 서버 대역폭 낭비, SEO 불이익(web vital 악화) 같은 문제를 유발할 수 있다. 이렇듯 성능뿐 아니라 사용자 경험과 접근성, 검색 최적화까지 영향을 미칠 수 있다.
Next.js next/image란?
Next.js는 next/image 컴포넌트를 통해 다음과 같은 기능을 기본 제공한다.
•
자동 Lazy Loading
•
반응형 이미지 자동 처리
•
WebP, AVIF 등 포맷 자동 전환
•
고해상도 대응(DPR에 따라 이미지 선택)
•
CDN 캐시 및 최적화
•
blur-up 프리뷰(저해상도 미리보기)
기본 사용법
import Image from 'next/image';
export default function Gallery() {
return (
<Imagesrc="/images/photo.jpg"
alt="풍경 이미지"
width={800}
height={600}
/>
);
}
TypeScript
복사
width와 height를 명시해야 CLS(Cumulative Layout Shift)를 방지할 수 있다.
*CLS(Cumulative Layout Shift): 콘텐츠가 얼마나 불안정한지 측정하는 지수. 높을 수록 안좋음.
자동 최적화 동작 원리
•
개발 환경: 로컬 서버에서 이미지 최적화 수행
•
프로덕션: Vercel 이미지 서버 또는 custom loader 사용
최적화 절차:
1.
이미지 크기 및 포맷 계산
2.
WebP 또는 AVIF로 변환
•
webp가 지원되지 않는 브라우저의 경우를 대비하기 위해 picture 태그를 쓴다.
<picture>
<source ... /> // webp
<img /> // jpg
</picture>
HTML
복사
3.
CDN 캐싱 후 응답
반응형 이미지: fill 속성
<div style={{ position: 'relative', width: '100%', height: '400px' }}>
<Imagesrc="/images/header.jpg"
alt="헤더 이미지"
fill
style={{ objectFit: 'cover' }}
/>
</div>
TypeScript
복사
부모 요소에는 반드시 position: relative를 설정해야 한다. next/image에서 fill 속성을 사용하면, 내부적으로 렌더링되는 <img> 요소는 다음과 같은 스타일이 적용되기 때문이다.
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
CSS
복사
즉, fill은 해당 이미지가 부모 요소를 기준으로 꽉 차도록 (100% 너비/높이) 만들기 위한 것이다. 그런데 이때 position: absolute는 CSS에서 다음 조건이 있어야 동작한다.
절대 위치(absolute)를 사용할 경우, 기준은 가장 가까운 position: relative | absolute | fixed | sticky를 가진 부모 요소이다.
만약 부모 요소가 position: static(기본값)이라면, 기준은 body로 올라가 버리고, 의도하지 않은 위치에 이미지가 배치된다.
Blur Placeholder로 UX 개선
<Image
src="/images/hero.jpg"
alt="대표 이미지"
width={1200}
height={800}
placeholder="blur"
blurDataURL="data:image/jpeg;base64,..."
/>
TypeScript
복사
•
로딩 중 저해상도 블러 이미지 노출로 사용자 경험 향상
•
blurDataURL을 프리로드하거나 CMS에서 미리 생성 필요
외부 이미지 최적화
next.config.js에서 외부 도메인을 허용해야 함:
module.exports = {
images: {
domains: ['images.unsplash.com', 'cdn.example.com'],
},
};
JavaScript
복사
이미지 로더 커스터마이징
const customLoader = ({ src, width }) => {
return `https://cdn.example.com/${src}?w=${width}`;
};
<Imageloader={customLoader}
src="images/example.jpg"
width={800}
height={600}
alt="Custom Loader Image"
/>
TypeScript
복사
•
Cloudflare, Imgix, Akamai 등 외부 이미지 최적화 서비스를 쓸 경우 유용
SVG는 어떻게 처리해야 할까?
SVG는 벡터 기반이기 때문에 <Image> 대신 일반적으로 다음 두 가지 방식 중 하나를 사용한다:
// 방법 1: img 태그
<img src="/logo.svg" alt="로고" />
// 방법 2: import하여 컴포넌트처럼 사용
import Logo from '../assets/logo.svg';
<Logo />
TypeScript
복사
제약 사항 및 주의점
•
CMS, 실시간 업로드 이미지의 경우 cache-control 설정 주의
•
SSR 환경에서는 <Image> 사용 시 클라이언트 사이드에서만 사용하는 방식은 제한적
•
SVG는 <Image>로 사용하지 않아야 함
•
퍼포먼스에 민감한 앱에서는 loader, 포맷, CDN 캐시 정책을 명확히 이해하고 적용해야 함
Next.js의 이미지 최적화 기능은 단순한 퍼포먼스 향상을 넘어 UX, 접근성, SEO를 종합적으로 고려한 설계이다.
next/image를 올바르게 사용하면 페이지 로딩 속도는 물론 사용자 만족도와 검색 랭킹까지 개선할 수 있다.