프론트엔드

최대한 효율적인 이미지 로딩을 목표로 브라우저 일시키기

마릴린벅시 2025. 9. 15. 18:00

 
웹에서 이미지 로딩은 성능과 사용자 경험에 큰 영향을 줍니다.
같은 이미지를 어떻게 제공하느냐에 따라 페이지 속도, 데이터 사용량, 화면 품질이 달라집니다.
이미지 최적화를 위해 두 가지 문법 접근 방식이 있습니다:

  • Descriptive Syntax (서술적 문법)
    → 브라우저에게 여러 후보 이미지를 제공하고, 브라우저가 스스로 선택하게 맡김.
  • Prescriptive Syntax (명령적 문법)
    → 개발자가 직접 조건을 지정하고, 어떤 이미지를 써야 할지 명시적으로 지시.

이 글에서는 효율적인 로딩을 위해 꼭 알아야 하는 서술적 문법 (Descriptive Syntax)에 대해 설명하겠습니다.


Descriptive Syntax란?

서술적 문법은 간단히 말해 :

브라우저야, 이미지 후보들은 내가 줄게. 어떤 걸 쓸지는 네가 판단해.

하는 방식입니다.
브라우저는 우리가 모르는 수많은 정보를 가지고 있습니다.

  • 사용자 기기의 화면 크기 (뷰포트)
  • 디스플레이 해상도 (DPR)
  • 네트워크 상태 (와이파이/5G/저속모드)
  • 사용자 설정 (데이터 절약 모드 등)

이런 정보는 개발자가 미리 알 수 없으니,
브라우저 스스로 판단하게 하는 것이 가장 합리적입니다.
즉, 개발자는 힌트만 제공하고, 최종 선택은 브라우저가 하도록 시키는 것입니다.
이를 위해 <img> 태그에서는 srcset + sizes 속성을 사용합니다.


 

srcset - 이미지 후보를 나열하기

srcset은 브라우저가 고를 수 있도록 여러 해상도의 이미지를 제공할 수 있게 해주는 속성입니다.
여기에는 x구문과 w구문이 있는데요,
하나씩 살펴보겠습니다.

 

1) x 구문 - 디스플레이 밀도 기준

x구문은 DPR을 기준으로 이미지 후보를 나열하는 구문입니다.
DPR이 뭔지 모르시는 분들은 이 글을 먼저 읽고 와주세요.

<img
  src="image@1x.jpg"
  srcset="
    image@1x.jpg 1x,
    image@2x.jpg 2x,
    image@3x.jpg 3x
  "
  alt="풍경사진">

 

  • DPR=1 기기에서는 image@1x.jpg 이미지가,
  • DPR=2 기기에서는 image@2x.jpg 이미지가,
  • DPR=3 기기에서는 image@3x.jpg 이미지가

적합하다고 브라우저에게 힌트를 주는 것입니다.
브라우저는 현재 기기의 DPR에 따라 가장 적합한 이미지를 선택합니다.
보시다시피 srcset에 DPR을 1x, 2x, 3x 이렇게 표현하고 있기 때문에 x구문이라고 합니다.
 
 

2) w 구문 - 이미지의 고유 너비 기준

각 파일이 몇 픽셀 너비인지 브라우저에 알려줍니다.

 

<img
  srcset="
    photo-600.jpg 600w,
    photo-1200.jpg 1200w,
    photo-2000.jpg 2000w
  "
  sizes="100vw"
  alt="반응형 이미지">

 
srcset에서의 w구문의 뜻은 이렇습니다 :

  • 600w → 이 파일은 원본 너비가 600px
  • 1200w → 이 파일은 원본 너비가 1200px
  • 2000w → 이 파일은 원본 너비가 2000px

그 밑의 sizes는, 화면에서 이 이미지가 몇 px로 차지할지 힌트를 주는 것입니다.
위의 태그를 전체적으로 해석하면 이렇습니다 :

  • 이 이미지는 뷰포트 너비의 100%를 차지할거다.
  • 내가 브라우저 너에게 각각 600px, 1200px, 2000px사이즈의 이미지를 줄테니
  • 사용자 뷰포트 너비에 따라서 알아서 골라서 보여줘라

 


sizes 속성 이해하기

sizes는 이미지가 실제 레이아웃에서 차지할 크기를 설명합니다.
x구문에서는 sizes속성이 필요 없지만, w구문에서는 sizes속성이 필요합니다.
 
왜냐하면 브라우저는 현재 디바이스의 DPR값은 이미 알고 있어서 추가 정보가 필요 없습니다.
그냥 현재 DPR에 맞춰 알맞은 이미지를 고르면 됩니다.
 
그러나 브라우저는 이미지 요청 시점에서 CSS 계산 결과를 모릅니다.
이미지를 화면에서 몇 px로 보여줄지 모르는데, 단순히 후보 목록(w)만 있으면 선택 기준이 부족합니다.
400px, 800px, 1600px이미지를 제공해도, 브라우저는 이걸 가지고 뷰포트에 몇 px로 보여줘야하는지 몰라서
어떤걸 선택할지 모른다는거죠.
그렇기 때문에 이 이미지를 얼마만큼의 크기로 렌더링해야 하는지 개발자가 힌트를 줘야합니다.

<img
  srcset="
    small.jpg 400w,
    medium.jpg 800w,
    large.jpg 1600w
  "
  sizes="(min-width: 1200px) 800px, 100vw"
  alt="responsive image">

 

  • 뷰포트 1200px 이상에서는 → 이미지가 800px 너비로 보인다
  • 그 외에는 → 뷰포트 100% 너비를 차지한다
  • 브라우저는 srcset의 후보 중 현재 가장 알맞은 이미지를 자동으로 선택한다
  • 만약 사용자가 현재 뷰포트를 1200px너비로 사용하고 있다면
    • sizes 조건 (min-width:1200px) 만족 → 렌더링 크기 = 800px
    • 브라우저는 800px 너비가 필요한 걸 알았으니, 후보 중 800w에 가장 근접한 medium.jpg 선택 ✅

 
하지만 중요한 건 뷰포트 크기뿐 아니라 DPR(Device Pixel Ratio)도 함께 고려한다는 점입니다.
예를 들어, 똑같이 뷰포트 1200px이어도 DPR=2라면
800px × 2 = 1600px 해상도를 요구할 수 있어서 large.jpg를 선택할 수도 있습니다.


데이터 절약 모드까지 고려

요즘 브라우저는 데이터 절약 모드까지 인식합니다.

@media (prefers-reduced-data: reduce) {
  img.hero {
    display: none; /* 무거운 이미지 비활성화 */
  }
}

 
즉, 단순히 해상도뿐 아니라 네트워크 환경까지고려해서 이미지 로딩 최적화가 가능합니다.


Next.js의 <Image> 태그는 어떻게 사용할까?

일반적인 html <img> 의 경우 개발자가 직접 srcset에 여러 해상도 이미지를 준비해둬야 합니다.

<img
  srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w"
  sizes="100vw"
  src="photo-800.jpg"
  alt="..."
/>

 

그러나 갓 Next.js는 이렇게 할 필요가 없습니다.
개발자는 원본 이미지 하나만 제공하고, sizes만 명시해주면 됩니다.

<Image src="/photo.jpg" sizes="100vw" width={100} height={100}/>

이렇게 하면 :
 

  • <Image>가 HTML srcset을 자동으로 생성해 넣어줌
    (ex. 320w, 640w, 1280w 등 여러 버전)
  • 하지만 실제 물리 파일은 개발자가 준비하지 않아도 됨
  • 브라우저가 특정 크기 이미지를 요청하면
    • → Next.js 서버는 원본을 받아 즉시 리사이즈/압축/포맷 변환해서 응답
    • → 결과는 캐시에 저장되어, 다음 요청부턴 빠르게 제공됨

 


요약

 

  1. Descriptive Syntax = 힌트 제공 → 브라우저가 최적의 이미지를 선택하도록 만드는 방법
  2. srcset으로 후보 제공, sizes는 레이아웃 힌트 → 브라우저가 알아서 결정하도록 함
  3. 사용자가 창 크기를 바꾸면 브라우저는 필요 시 더 큰 이미지를 다시 요청한다.
  4. Next.js <Image> 컴포넌트는 이 로직을 자동 최적화해준다. sizes만 잘 지정해주면, 최적화된 이미지를 자동으로 변환 및 전송합니다.

마무리

갓스트.js