이미지 태그 잘 사용하기

park·2026년 7월 17일

브라우저는 어떤 이미지를 다운로드할까?

img, srcset, picture, lazy loading 이해하기

웹 페이지에서 이미지를 표시할 때 가장 먼저 떠오르는 태그는 img 태그다.

<img src="/product.jpg" alt="상품 이미지" />

이미지를 화면에 보여주는 것만 생각한다면 이것으로 충분해 보인다.

하지만 문득 이런 궁금증이 들었다.

화면에는 200px 크기로 보이는데, 브라우저는 정말 200px 크기의 이미지만 다운로드하고 있을까?

이 질문을 시작으로 img, srcset, picture, lazy loading이 왜 등장하게 되었는지 정리해보았다.


img 태그만 사용하면 어떤 일이 일어날까?

다음과 같은 이미지가 있다고 가정해보자.

  • 실제 이미지 크기: 1200 × 1200
  • 파일 용량: 500KB

그리고 화면에서는 아래처럼 렌더링된다.

<img src="/product.jpg" alt="상품 이미지" />
img {
  width: 200px;
  height: 200px;
}

사용자 눈에는 200px 크기로 보인다.

하지만 브라우저는 CSS가 적용된 최종 렌더링 크기를 기준으로 이미지를 다운로드하지 않는다.

src에 명시된 원본 이미지를 다운로드한 뒤, 렌더링 과정에서 200px 크기로 축소한다.

즉,

  • 보여지는 크기: 200px
  • 다운로드되는 크기: 1200px

일 수 있다.

이미지 한 장이라면 큰 문제가 아닐 수 있다.

하지만 상품 목록 페이지처럼 이미지가 수십 개 존재한다면 이야기가 달라진다.

500KB × 20장 = 10MB

사용자는 실제로 필요하지 않은 데이터를 다운로드하고 있을 수도 있다.


브라우저는 어떤 이미지를 내려받아야 하는지 모른다

사실 브라우저 입장에서는 당연한 행동이다.

<img src="/product.jpg" />

이 정보만 보고는

  • 사용자의 화면 크기
  • 디바이스 해상도
  • 실제 렌더링 크기

를 정확히 판단할 수 없다.

브라우저는 단순히

"product.jpg를 요청하라고 했으니 product.jpg를 다운로드해야겠다."

라고 생각한다.

그래서 등장한 것이 srcset이다.


srcset은 어떤 문제를 해결할까?

srcset은 브라우저에게 여러 크기의 이미지 후보를 제공하는 기능이다.

<img
  src="product-400.jpg"
  srcset="
    product-400.jpg 400w,
    product-800.jpg 800w,
    product-1200.jpg 1200w
  "
  alt="상품 이미지"
/>

이제 브라우저는

  • 현재 화면 크기
  • 디바이스 픽셀 비율(DPR)

을 고려하여 적절한 이미지를 선택할 수 있다.

예를 들어

환경선택되는 이미지
모바일400px
태블릿800px
데스크톱1200px

처럼 동작할 수 있다.

즉, 브라우저가 상황에 맞는 이미지를 스스로 선택할 수 있게 된다.


Retina 디스플레이에서는 어떻게 될까?

같은 200px 영역이라도 디바이스마다 필요한 이미지 크기가 다르다.

예를 들어 DPR(Device Pixel Ratio)이 2인 환경에서는

200px 영역
↓
실제로는 400px 이미지 필요

할 수 있다.

그래서 브라우저는 단순히 화면 크기만 보는 것이 아니라 디바이스 해상도까지 고려해서 이미지를 선택한다.

srcset이 없다면

  • 너무 큰 이미지를 받거나
  • 너무 작은 이미지를 받아 흐릿하게 보이는

문제가 발생할 수 있다.


picture 태그는 왜 등장했을까?

srcset은 같은 이미지의 크기만 바꾸는 데 적합하다.

하지만 경우에 따라서는 아예 다른 이미지를 제공해야 할 수도 있다.

예를 들어

  • 모바일에서는 세로 이미지
  • 데스크톱에서는 가로 이미지

를 보여주고 싶을 수 있다.

이때 사용하는 것이 picture 태그다.

<picture>
  <source
    media="(min-width: 768px)"
    srcset="/banner-desktop.jpg"
  />

  <source
    media="(max-width: 767px)"
    srcset="/banner-mobile.jpg"
  />

  <img src="/banner.jpg" alt="배너" />
</picture>

브라우저는 조건에 맞는 이미지를 선택하여 렌더링한다.

즉,

srcset은 "어떤 크기의 이미지를 사용할까?"를 해결하고,

picture는 "어떤 이미지를 사용할까?"를 해결한다.


이미지 포맷도 최적화 대상이다

이미지 최적화는 크기만의 문제가 아니다.

포맷 역시 중요하다.

일반적으로 다음과 같은 압축 효율을 가진다.

포맷상대 용량
JPG100%
WebP60~80%
AVIF40~70%

이를 활용하면 같은 이미지를 더 작은 용량으로 제공할 수 있다.

<picture>
  <source
    srcset="/product.avif"
    type="image/avif"
  />

  <source
    srcset="/product.webp"
    type="image/webp"
  />

  <img src="/product.jpg" alt="상품" />
</picture>

브라우저는 지원 가능한 가장 효율적인 포맷을 선택한다.


모든 이미지를 한 번에 다운로드해야 할까?

상품 목록 페이지를 생각해보자.

사용자가 처음 보는 영역은 화면 상단뿐이다.

그런데 아래쪽에 있는 이미지까지 모두 다운로드한다면 어떨까?

초기 로딩 시간이 길어질 수 있다.

이를 해결하기 위해 등장한 것이 Lazy Loading이다.

<img
  src={imageUrl}
  alt={name}
  loading="lazy"
/>

브라우저는 해당 이미지가 화면에 가까워졌을 때 다운로드를 시작한다.

결과적으로

  • 초기 페이지 로딩 속도 개선
  • 네트워크 사용량 감소

효과를 얻을 수 있다.

특히 무한 스크롤이나 상품 목록 페이지에서 유용하다.


CLS는 왜 발생할까?

이미지와 관련하여 자주 언급되는 성능 지표 중 하나가 CLS(Cumulative Layout Shift)다.

다음 코드를 보자.

<img src="/product.jpg" alt="상품" />

브라우저는 이미지 크기를 알 수 없기 때문에 처음에는 공간을 확보하지 못한다.

이후 이미지가 로딩되면 갑자기 공간이 생기면서 화면이 밀릴 수 있다.

사용자는

  • 읽고 있던 위치가 바뀌고
  • 버튼 위치가 움직이고
  • 의도치 않은 클릭을 하게 될 수도 있다

이를 방지하려면 이미지 크기를 미리 알려주는 것이 좋다.

<img
  src="/product.jpg"
  alt="상품"
  width="300"
  height="300"
/>

또는 CSS의 aspect-ratio를 활용할 수도 있다.


정리

처음에는 단순히 이미지를 보여주는 태그라고 생각했던 img 태그가 생각보다 많은 고민을 담고 있다는 것을 알게 되었다.

이미지 최적화는 단순히 파일 용량을 줄이는 것이 아니다.

브라우저가

  • 어떤 이미지를 다운로드해야 하는지
  • 언제 다운로드해야 하는지
  • 어떤 포맷을 사용해야 하는지

를 효율적으로 결정할 수 있도록 돕는 과정에 가깝다.

정리하면,

  • srcset : 적절한 크기의 이미지를 선택하기 위해
  • picture : 상황에 따라 다른 이미지를 제공하기 위해
  • WebP / AVIF : 더 작은 용량으로 전달하기 위해
  • loading="lazy" : 필요한 시점에 다운로드하기 위해
  • width / height : CLS를 방지하기 위해

사용할 수 있다.

실제로 원본 이미지(1200px)와 srcset 적용 후 다운로드 크기를 비교한 실험 결과를 추가해볼 예정

profile
park

0개의 댓글