<img/> vs <Image />, 유연하게 대처하기
Next.js 기반의 프로젝트를 진행 중, 동료가 모든 이미지에 대해
Image 컴포넌트를 사용하는 것을 peer riview 도중 파악했습니다.
동료분에게 리뷰로 짧게 설명하기보단 문서화를 통해서
Next.js 환경에서는 꼭 Image 컴포넌트만 사용해야 할까?라는 것을
말씀드리고 싶었고, 당시 전하고자 하는 내용을 블로그에도 포스팅해보았습니다.
🤷🏻♂️ 둘의 사용 시점은 서로 다릅니다.
HTML <img> 태그를 사용하는 경우:
- 매우 작은 크기의 아이콘이나 데코레이션용 이미지 (10x10 px 같은 경우)
- 정적이고 변경되지 않는 작은 이미지
- 성능 최적화가 크게 중요하지 않은 경우
- 외부 이미지나 SVG 아이콘
- 로딩 시간이나 레이아웃 시프트가 중요하지 않은 상황
Next.js Image 컴포넌트를 사용하는 경우:
- 다양한 디바이스/해상도에 대응해야 하는 반응형 이미지
- 성능 최적화가 중요한 콘텐츠 이미지
- 동적으로 크기가 변경되는 이미지
- 레이아웃 시프트를 방지해야 하는 이미지
- 자동 이미지 최적화(WebP, AVIF 등)가 필요한 경우
- 지연 로딩(Lazy Loading)이 필요한 이미지
// 작은 아이콘의 경우엔 <img> 태그가 좋음.
<img src="/icon.svg" width={10} height={10} alt="Small icon" />
// 콘텐츠 이미지의 경우엔 Image 컴포넌트 사용이 좋음.
<Image
src="/large-product-image.jpg"
width={800}
height={600}
alt="Product"
quality={75}
sizes="(max-width: 768px) 100vw, 50vw"
/>
결론적으로, 10px x 10px 크기의 아이콘과 같은
매우 작고 간단한 이미지에는 굳이 Image 컴포넌트를 사용할 필요가 없습니다.
하지만 콘텐츠 이미지나 성능에 민감한 이미지는
Image 컴포넌트의 최적화 기능을 적극 활용하는 것이 좋습니다.
🤔 작은 이미지를 처리할 땐 별다른 처리 없이 <img />만 사용해도 되는 걸까?
결론부터 말하자면 아닙니다.
HTML <img> 태그를 사용할 때 작은 이미지에 대해서도 최적화를 고려해야 합니다.
<img />를 사용할 때의 최적화 방법
1. 포맷 최적화
- SVG 사용 (벡터 기반, 작은 파일 크기)
- WebP 포맷
- AVIF 포맷 (더 작은 파일 크기, 브라우저마다 다르게 포맷 처리가 이뤄져 주의)
2. 속성 최적화
- loading="lazy": 필요할 때만 로딩
- width, height 명시: 레이아웃 시프트 방지
- alt 속성 추가
3. 추가 최적화 방법
- 여러 이미지/아이콘을 단일 파일로 결합한 Sprite sheet 활용
- Base64 인코딩 (이미지가 매우 작은 경우)
example)
<img
src="/icon.svg"
width="10"
height="10"
alt="Icon"
loading="lazy"
/>
작은 아이콘의 경우 대부분 SVG나 인라인 SVG를 사용해 주는 것이 좋습니다.
SVG를 사용하지 않는다면 webp를 사용하는 방법도 있겠네요!
🚀 <img />, <Image /> 외의 다른 최적화 기법을 찾아보자
1. 이미지 CDN 활용
- Cloudinary, Imgix, Amazon S3 등을 사용.
- 자동 포맷 변환, 실시간 이미지 리사이징, 최적의 품질/크기 자동 선택을 통해 최적화 가능.
2. 프로그레시브 이미지 로딩
- LQIP (Low Quality Image Placeholder).
- 점진적으로 선명한 이미지로 교체하는 기법.
- 로드 중인 초기 이미지는 블러 처리, 로드가 완료되었다면 온전한 이미지로 보여주기.
3. 크리티컬 CSS 접근법
- 이미지 로딩 전 placeholder 영역을 미리 스타일링해놓는 기법으로 레이아웃 흔들림 방지 가능.
- 스켈레톤 UI가 대표적인 예시.
4. 자동 최적화 도구
- 개발 환경에서는 Squoosh, 운영 환경에서는 sharp 기반의 최적화를 진행하는 것이 효율적.
- sharp vs Squoosh
- WebP 포맷으로 최적화할 때는 3~4배, AVIF 포맷으로 최적화할 때는 3~6배 정도의 성능 개선.
- sharp vs Squoosh
- 이외에도 ImageOptim라는 소프트웨어를 사용해 이미지 파일 사이즈를 감소시키는 방법도 존재합니다.
(저는 사용해보진 않았습니다.)
5. 웹 표준 기법
- <picture> 태그 활용
- srcset, sizes 속성으로 반응형 대응
- 해상도에 따라 같은 이미지를 고화질로 보여주고 싶을 때 img srcset을, 해상도에 따라 다른 이미지
or 다른 포맷을 보여주고 싶을 때에는 picture를 사용하면 됩니다.
🧩 Bonus) 왜 SVG를 사용하면 최적화가 되는 걸까?
최적화가 가능한 이유는 SVG의 본질적 특징에 있습니다.
벡터 기반 그래픽이기 때문에 사이즈를 조정해도 품질 손실이 없을 뿐만 아니라
최소한의 path, 색상, 그라데이션만 사용하기 때문에
PNG, JPEG(= 래스터 이미지)보다 파일 크기가 작습니다.
이러한 이유로 SVG를 통한 이미지 최적화가 가능합니다.
reference)
NEXT.JS의 이미지 최적화는 어떻게 동작하는가? | 올리브영 테크블로그
그 외 검색과 클로드