반응형 이미지를 알아보자

chaeruru·2021년 9월 5일
0

이미지 최적화의 다양한 방법 중 반응형 이미지를 직접 사용해보기 위해서 공부를 해보았다.

반응형 이미지는 간략하게 설명하면, 다양한 기기의 뷰포트에 맞게 최적의 이미지를 제공하는 것이다.

예를 들어서 뷰포트가 넓은 데스크탑에서 사용하는 이미지를 그대로 모바일 기기에서 사용한다면 이미지에 따라 화면을 너무 많이 차지하거나, 이미지가 잘 보이지 않는 등 크고작은 문제가 생길 수 있다.

반응형 이미지를 사용하는 이유

아트 디렉션

데스크탑 화면에서 보이던 이미지가 모바일 기기로 봤을 때 이미지가 나타내고자 하는 중요한 부분이 작게 보이거나 안 보일 수가 있다. 그럼 이를 위한 해결책은 이미지의 중요한 상세를 위주로 이미지를 잘라서 보여주는 것이다. 이렇게 반응형 이미지에서 이미지의 의도가 제대로 전달되도록 기기에 따라 사진의 핵심을 확대해서 보여주는 방식을 아트 디렉션이라 한다.

해상도 전환

모바일화면에서 보여주는 이미지 크기가 데스크탑 화면에서 보여주는 이미지 크기와 같을 필요가 있을까? 모바일 화면이 더 작기 때문에 당연히 같을 필요가 없다. 오히려 같은 크기의 이미지를 보여준다면 그것은 대역폭을 낭비한다. 따라서 다양한 해상도의 사진을 준비하고 기기에 따라 최적의 사이즈를 제공한다.

반응형 이미지 사용하기

MDN 에서 제공하는 예제 페이지를 통해 진행

https://mdn.github.io/learning-area/html/multimedia-and-embedding/responsive-images/responsive.html

아트 디렉션

이때까지 이미지를 제공하기위해 <img> 만 사용했다면 <picture> , <source> , <img> 태그를 사용해보자

Before

<img src="elva-800w.jpg" alt="딸 엘바를 안고 서 있는 크리스">

모바일 뷰임에도 elva-800w.jpg 이미지를 요청한다.

After

<picture>
  <source media="(max-width: 799px)" srcset="elva-480w-close-portrait.jpg">
  <source media="(min-width: 800px)" srcset="elva-800w.jpg">
  <img src="elva-800w.jpg" alt="딸 엘바를 안고 서 있는 크리스">
</picture>
  • <source> 에 있는 media 속성을 통해 뷰포트 너비가 799px 이하라면 첫 번째 <source> 의 이미지가 아니라면 두 번째 <source> 의 이미지가 표시된다.
  • <picture> 를 지원하지 않는 경우 fallback으로 <img> 를 넣어준다. <img> 는 반드시 맨 마지막, </picture> 바로 위에 있어야 올바르게 이미지가 표시된다.

뷰포트에 맞게 모바일 뷰일 때 elva-480w-close-portrait.jpg를 요청한다.

해상도 전환

<img>srcset , sizes , src 속성을 사용해보자

Before

<img src="elva-fairy-800w.jpg" alt="요정 옷을 입은 엘바">

After

<img srcset="elva-fairy-320w.jpg 320w,
             elva-fairy-480w.jpg 480w,
             elva-fairy-800w.jpg 800w"
     sizes="(max-width: 320px) 280px,
            (max-width: 480px) 440px,
            800px"
     src="elva-fairy-800w.jpg" alt="요정 옷을 입은 엘바">

srcset

  • 이미지 파일명
  • 이미지 고유 픽셀 너비 (단 px이 아니라 w 사용). 이미지의 실제 사이즈를 입력한다.

sizes

  • 미디어 조건문
  • 미디어 조건문이 참인 경우 이미지가 채울 슬롯의 너비 px, em, vw 가 올 수 있음 (%)는 안됨

src

  • 브라우저가 위의 기능을 지원하지 않는 경우 제공하는 fallback

브라우저 동작

  1. 기기 너비 확인
  2. sizes 목록에서 가장 먼저 참이 되는 미디어 조건문을 확인한다.
  3. 해당 미디어 쿼리가 제공하는 슬롯 크기를 확인한다.
  4. 해당 슬롯 크기에 가장 근접하게 맞는 srcset 에 연결된 이미지를 불러온다.

이미지 비율

<img srcset="elva-fairy-320w.jpg,
             elva-fairy-480w.jpg 1.5x,
             elva-fairy-640w.jpg 2x"
     src="elva-fairy-640w.jpg" alt="요정 옷을 입은 엘바">

x 는 디바이스 픽셀 비율과 일치하는 값으로 최적화 선택한다.

w 를 사용하면 x 를 사용하지 않아도 된다.

마무리

<img>srcset 에서 w 를 사용하여 직접해보면서 <picture><source> 를 이용했을 때와 달리 뷰포트 크기에 따라 네트워크 요청에 변화가 없는 것이 의아했다. 내 생각은 미디어 쿼리에 따라 그에 맞는 사이즈의 이미지가 요청될 줄 알았는데 아니었다.

여러가지 조사를 해본 결과

첫 번째로 브라우저가 큰 이미지를 한 번 불러왔다면 오히려 해상도가 떨어지는 작은 이미지를 또 불러올 필요를 느끼지 못해 이미지 갱신이 일어나지 않는다.

두 번째로 개발자의 의도대로가 아닌 브라우저가 스스로 최적의 이미지를 고르기 때문이다. 즉 우리는 srcset 을 이용하여 브라우저에게 후보군을 준 것 뿐이고 선택은 브라우저가 최선의 상황에 맞게 이미지를 선택한다.

세 번째로 디스플레이에 따른 픽셀 밀도 및 디스플레이 확대/축소 비율차이이다. 이것도 두 번째 이유와 비슷하다. srcset 에서 w 로 명시를 했지만 디스플레이의 픽셀 밀도에 따라 이미지를 제공한다. 따라서 같은 코드여도 mac은 레티나 디스플레이로 고해상도 디스플레이기 때문에 mac일 때와 window 일 때 불러오는 이미지가 다를 수 있다.

간단히 요약하면 <img>srcset 을 이용하여 반응형 이미지를 제공할 때는 개발자는 그저 이미지 후보만 제공하고 선택은 브라우저가 현재 최선에 맞는 이미지를 고른다는 것이다.

Reference

반응형 이미지 - Web 개발 학습하기 | MDN

HTML IMG의 srcset과 sizes 속성(updated)

profile
알고리즘과 프론트엔드 부셔버리기

0개의 댓글