개요

웹 페이지 용량의 절반 이상을 이미지가 차지하는 경우가 많습니다. 반응형 이미지 최적화는 사용자의 디바이스와 네트워크 환경에 맞는 최적의 이미지를 전달하여 성능과 사용자 경험을 모두 향상시키는 기술입니다.

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 포맷으로 최적의 압축을 달성하면, 대역폭을 절약하면서 사용자에게 빠른 로딩 경험을 선사할 수 있습니다. 이미지 최적화는 한 번 설정하면 지속적으로 효과가 있으므로, 꼭 프로젝트에 적용해 보시기 바랍니다.