인턴

[ Troubleshooting🛠️ ] HTML <picture>과 <source> 태그 활용하기

choijming21 2025. 3. 25. 11:52

안녕하세요! 오늘은 제가 프로젝트에서 마주친 반응형 이미지 렌더링 문제와 해결 방법에 대해 공유하려고 합니다.

 

 

1.  문제 발생❓

제 프로젝트에서는 breakpoint가 768px로만 설정되어 있었지만, 이미지는 mobile, tablet, desktop 세 가지 디바이스 크기에 맞춰 렌더링해야 했습니다. 이런 요구사항을 어떻게 효율적으로 구현할지 고민하던 중 HTML의<picture>와 <source> 태그를 알게 되었습니다.

 

 

 

2.  해결 과정 📋

< picture 태그 활용하기 >

HTML5에서 도입된 <picture> 태그는 다양한 화면 크기와 해상도에 맞는 이미지를 제공하는 강력한 방법입니다. 이 태그는 <source> 태그와 함께 사용하여 미디어 쿼리에 따라 적절한 이미지를 자동으로 선택해 줍니다.

 

< 구현 코드 >

import React from "react";
import { DesktopViewContainer } from "../DesktopViewContainer";

const CDN_BASE_URL = process.env.NEXT_PUBLIC_CDN_BASE_URL!;

const ResponsiveSection = () => {
  return (
    <section className="flex justify-center w-full bg-gradient-to-b from-[#2d3c49] to-[#090b0d]">
      <DesktopViewContainer size="xl" className="w-full h-auto">
        <picture>
          <source
            srcSet={`${CDN_BASE_URL}/japan/accomplish-mobile.webp`}
            media="(max-width: 768px)"
          />
          <source
            srcSet={`${CDN_BASE_URL}/japan/accomplish-tablet.webp`}
            media="(max-width: 1024px)"
          />
          <source
            srcSet={`${CDN_BASE_URL}/japan/accomplish-pc.webp`}
            media="(max-width: 1440px)"
          />
          <img
            src={`${CDN_BASE_URL}/japan/accomplish-pc.webp`}
            alt="accomplish"
            draggable={false}
            className="select-none"
          />
        </picture>
      </DesktopViewContainer>
    </section>
  );
};

export default ResponsiveSection;

 

< 코드 설명 >

  • <picture> 태그 안에 여러 개의 <source> 태그를 배치하고, 각각 다른 미디어 쿼리 조건을 설정했습니다.
  • 브라우저는 위에서부터 순서대로 <source> 태그의 media 속성을 확인하여 조건에 맞는 첫 번째 이미지를 선택합니다.
    • 화면 너비가 768px 이하면 모바일 이미지
    • 화면 너비가 1024px 이하면 태블릿 이미지
    • 화면 너비가 1440px 이하면 PC 이미지
  • 마지막에 <img> 태그를 포함하여 <picture> 태그를 지원하지 않는 브라우저를 위한 대체 이미지도 제공했습니다.

 

< 성능 향상 핵심 >

가장 중요한 점은 <picture> 태그와 <source> 태그를 사용하면 필요한 이미지만 다운로드 한다는 것입니다.

일반적은 CSS 미디어 쿼리 방식과 달리, 브라우저 조건에 맞는 이미지 하나만 다운로드 합니다. 예를 들어:

  • 모바일 환경에서는 모바일 이미지만 다운로드
  • 태블릿 환겨에서는 태블릿 이미지만 다운로드
  • 데스크톱 환경에서는 PC 이미지만 다운로드

이는 다음과 같은 성능 이점을 제공합니다:

  • 불필요한 네트워크 트래픽 감소
  • 로딩 시간 단축
  • 사용자 데이터 사용량 절약
  • 서버 부하 감소

CSS의 display: none을 사용한 방식과는 달리, 브라우저는 화면에 보이지 않는 이미지도 모두 다운로드 하는 반면, <picture> 태그는 실제로 렌더링할 이미지만 다운로드 합니다.

 

 

< 장점 >

  • 서버에서 디바이스별로 다른 이미지를 전송할 필요 없이 클라이언트 측에서 적절한 이미지를 자동 선택
  • 미디어 쿼리를 통해 세밀한 반응형 제어 가능
  • WebP와 같은 최신 이미지 포맷 사용으로 로딩 속도 향상
  • 코드가 직관적이고 유지보수가 쉬움
  • 필요한 이미지만 다운로드 하여 네트워크 리소스 절약

< 주의점 > 

  • <source> 태그의 순서가 중요합니다. 브라우저는 위에서부터 순서대로 조건을 확인합니다.
  • 모든 브라우저가 WebP 포맷을 지원하는 것은 아니므로, 필요한 경우 대체 포맷도 제공해야 합니다.

 

 

 

3.  결과 ❤‍🔥

이 방법으로 프로젝트에서 필요한 반응형 이미지 렌더링을 효과적으로 구현할 수 있었을 뿐만 아니라, 페이지 로딩 시간과 네트워크 사용량을 크게 개선할 수 있었습니다. 비슷한 문제를 겪고 계신다면 한번 시도해보세요!