Contents
see List개요
웹 페이지 용량의 절반 이상을 이미지가 차지하는 경우가 많습니다. 반응형 이미지 최적화는 사용자의 디바이스와 네트워크 환경에 맞는 최적의 이미지를 전달하여 성능과 사용자 경험을 모두 향상시키는 기술입니다.
HTML의 srcset, sizes 속성과 <picture> 요소는 반응형 이미지의 핵심이며, 여기에 AVIF와 WebP 같은 차세대 이미지 포맷을 결합하면 극적인 성능 향상을 달성할 수 있습니다. 2025년 현재 AVIF는 Chrome, Firefox, Safari 모두에서 지원되어 실전 투입이 가능합니다.
핵심 개념
반응형 이미지의 세 가지 핵심 메커니즘을 이해해야 합니다.
- srcset: 동일 이미지의 다양한 크기(해상도) 버전을 브라우저에 제공하여, 브라우저가 최적의 것을 선택하게 합니다.
- sizes: 이미지가 뷰포트에서 차지할 실제 크기를 브라우저에 알려줍니다. srcset의 선택 기준이 됩니다.
- picture 요소: 포맷별(AVIF, WebP, JPEG), 미디어 쿼리별로 다른 이미지 소스를 제공하는 컨테이너입니다.
- AVIF: AV1 비디오 코덱 기반 이미지 포맷으로, WebP보다 20-30% 더 작은 파일 크기에 동등한 품질을 제공합니다.
- loading="lazy": 뷰포트에 가까워질 때 이미지를 로드하여 초기 페이지 성능을 개선합니다.
실전 예제
포맷 최적화와 반응형을 모두 적용한 완전한 이미지 마크업 예제입니다.
<!-- 기본: srcset과 sizes로 해상도별 이미지 제공 -->
<img
src="hero-800.jpg"
srcset="
hero-400.jpg 400w,
hero-800.jpg 800w,
hero-1200.jpg 1200w,
hero-1600.jpg 1600w
"
sizes="
(max-width: 600px) 100vw,
(max-width: 1200px) 50vw,
33vw
"
alt="히어로 배너 이미지"
width="1600"
height="900"
loading="lazy"
decoding="async"
>
<!-- 고급: picture로 포맷별 + 해상도별 최적화 -->
<picture>
<!-- AVIF: 최고 압축률 -->
<source
type="image/avif"
srcset="
photo-400.avif 400w,
photo-800.avif 800w,
photo-1200.avif 1200w
"
sizes="(max-width: 768px) 100vw, 50vw"
>
<!-- WebP: 넓은 호환성 -->
<source
type="image/webp"
srcset="
photo-400.webp 400w,
photo-800.webp 800w,
photo-1200.webp 1200w
"
sizes="(max-width: 768px) 100vw, 50vw"
>
<!-- JPEG: 최종 폴백 -->
<img
src="photo-800.jpg"
srcset="
photo-400.jpg 400w,
photo-800.jpg 800w,
photo-1200.jpg 1200w
"
sizes="(max-width: 768px) 100vw, 50vw"
alt="최적화된 사진"
width="1200"
height="800"
loading="lazy"
decoding="async"
>
</picture>
<!-- 아트 디렉션: 디바이스별 다른 이미지 -->
<picture>
<source
media="(max-width: 768px)"
srcset="banner-mobile.avif"
type="image/avif"
>
<source
media="(max-width: 768px)"
srcset="banner-mobile.jpg"
>
<img src="banner-desktop.jpg" alt="배너" width="1920" height="600">
</picture>
/* 이미지 레이아웃 시프트 방지 */
img {
max-width: 100%;
height: auto;
/* aspect-ratio로 공간 확보 (CLS 방지) */
aspect-ratio: attr(width) / attr(height);
}
/* 페이드인 로딩 효과 */
img[loading="lazy"] {
opacity: 0;
transition: opacity 0.3s ease;
}
img[loading="lazy"].loaded,
img[loading="lazy"][complete] {
opacity: 1;
}
/* 배경 이미지에 image-set() 사용 */
.hero-section {
background-image: image-set(
url("hero-bg.avif") type("image/avif"),
url("hero-bg.webp") type("image/webp"),
url("hero-bg.jpg") type("image/jpeg")
);
background-size: cover;
}
활용 팁
- width와 height 속성을 반드시 명시하세요. 브라우저가 이미지 로드 전에 공간을 확보하여 CLS(Cumulative Layout Shift)를 방지합니다.
- LCP(Largest Contentful Paint) 이미지에는
loading="lazy"를 사용하지 마세요. 대신fetchpriority="high"를 사용합니다. - 빌드 도구로 자동화하세요. sharp, squoosh, 또는 Next.js Image 컴포넌트를 사용하면 여러 포맷과 크기의 이미지를 자동 생성할 수 있습니다.
- AVIF 품질 설정: quality 50-60 정도면 JPEG quality 80과 비슷한 시각 품질을 얻으면서 파일 크기는 훨씬 작습니다.
- CDN의 이미지 최적화 기능(Cloudflare Images, Vercel Image Optimization 등)을 활용하면 수동 작업을 최소화할 수 있습니다.
마무리
반응형 이미지 최적화는 웹 성능 개선에서 가장 효과가 큰 영역 중 하나입니다. srcset과 sizes로 적절한 크기의 이미지를 제공하고, picture 요소와 AVIF 포맷으로 최적의 압축을 달성하면, 대역폭을 절약하면서 사용자에게 빠른 로딩 경험을 선사할 수 있습니다. 이미지 최적화는 한 번 설정하면 지속적으로 효과가 있으므로, 꼭 프로젝트에 적용해 보시기 바랍니다.