[Develop] 이미지 최적화

jinni·2025년 10월 22일

Develop

목록 보기
2/2

웹 페이지에서 이미지는 전체 용량의 50~70%에 달할 만큼 큰 비중을 차지합니다.

즉, 이미지 최적화는 웹 성능 향상에서 가장 즉각적이고 효과적인 개선 수단입니다.

프론트엔드에서 이미지 성능을 최적화해야 하는 이유는 단순히 “용량을 줄이기 위해서”라기 보다, 웹 성능, UX, SEO, 비용 전반에 영향을 미치는 핵심 요소이기 때문입니다.

이미지 성능을 최적화 해야하는 이유

  1. 로딩 속도 개선
    • 이미지가 크면 네트워크 요청이 지연되고, TTFP(Time to First Paint) LCP(Largest Contentful Paint) 지표에 직접적인 영향을 줍니다.
    • LCP가 느리면 사용자는 “사이트가 느리다”고 인식하고 이탈합니다.
  2. UX 품질 향상
    • 이미지는 시각적 중심이기 때문에 렌더링 지연 시 사용자 만족도가 급격히 하락합니다.
    • 사용자는 로딩이 3초 이상 걸리면 53%가 페이지를 이탈한다는 통계가 있습니다.
  3. SEO 및 Core Web Vitals 영향
    • Google은 페이지의 LCP/CLS/FID를 랭킹 신호로 사용합니다.
    • 이미지가 비효율적으로 로딩되면 LCP가 나빠지고, lazy loading을 잘못 적용하면 CLS가 깨집니다.
  4. CDN, 데이터 요금 및 에너지 낭비
    • 불필요하게 큰 이미지는 CDN 비용과 사용자의 모바일 데이터 소모를 증가시킵니다.
    • 이미지 최적화는 지속 가능한 웹 성능 측면에서도 중요합니다.

이미지 최적화 방법

전송 최적화

  1. 포맷 최적화

WebP, AVIF 같은 차세대 포맷은 기존 JPEG 대비 30~80% 용량 절감 효과가 있다.

구글의 테스트 결과(https://developers.google.com/speed/webp/docs/webp_study?hl=ko)

포맷평균 파일 크기JPEG 대비 절감률
JPEG100%
WebP (lossy)~73%27% 절감
WebP (lossless)~74%26% 절감

넷플릭스의 테스트 결과 (https://netflixtechblog.com/avif-for-next-generation-image-coding-b1d75675fe4)

포맷평균 파일 크기 (기준 JPEG=100%)절감률
JPEG100%
WebP74%-26%
AVIF50%-50% (JPEG 대비 절반)

AVIF는 WebP 포맷보다 더 높은 압축률을 보이지만, 인코딩 속도가 더 느리기 때문에 목적에 맞도록 사용하는 것이 좋다.

사용 환경더 나은 선택이유
정적 웹사이트 (이미지를 미리 빌드해두는 경우)AVIF한 번 인코딩하면 오래 캐시됨, 용량 절약 효과 큼
사용자 업로드 많은 서비스 (예: SNS, 블로그)WebP인코딩 빠름, 서버 부하 적음
실시간 생성 썸네일, 이미지 프록시WebP속도가 중요하므로
CDN 기반 서비스 (이미지 캐싱 중심)AVIF + WebP fallback캐싱 후 디코딩 성능 문제 없음
  1. 적절한 사이즈 제공

모든 디바이스에 동일한 해상도를 전송하는 것은 낭비이다.

HTML5의 srcset/sizes 속성을 사용하여 해상도별로 적절한 이미지를 제공한다.

<img
  src="/image-800.jpg"
  srcset="/image-400.jpg 400w, /image-800.jpg 800w, /image-1600.jpg 1600w"
  sizes="(max-width: 600px) 400px, 800px"
  alt="responsive example"
/>
  1. 캐싱 및 CDN 활용

이미지 정적 리소스는 반드시 Cache-Control 헤더를 설정해야한다.

또한, 이미지 리소스를 CDN에 배포하여 지리적 거리 문제를 최소화 할 수 있다.

  1. 압축 및 빌드단 자동화

개발 단계에서 sharp , imagemin, squoosh 등을 이용해 압축을 자동화 할 수 있다.

렌더링 최적화

  1. Lazy Loading

화면에 보이지 않는 이미지를 지연 로딩하여 초기 렌더링 부담을 줄일 수 있다.

<img src="/photo.webp" loading="lazy" alt="lazy image" />

Hero 이미지(첫 화면에 핵심 이미지)는 loading=”lazy” 를 사용하지 않아야 한다. (LCP 지연의 원인이 된다.)

  1. 이미지 크기 면시

<img>width , height 를 지정하지 않으면 레이아웃 시프트(CLS)가 발생한다.

  1. Next.js Image Optimization

Next.js는 <Image> 컴포넌트를 통해 자동으로 최적화된 포맷, 크기, lazy loading을 처리한다.

import Image from 'next/image';

<Image
  src="/hero.jpg"
  alt="Hero"
  width={1200}
  height={600}
  priority // Hero 영역은 즉시 로드
/>
  1. Preload 이미지

Hero 이미지나 LCP 대상 이미지는 <link rel="preload"> 를 사용해 미리 요청한다.

네트워크 레이턴시 최적화

HTTP 요청 수를 줄여 네트워크 레이턴시를 최소화하는 기법이다.

스프라이트(Sprite) 기법

스프라이트란 여러 개의 아이콘이나 이미지를 하나의 파일로 합쳐서 관리하고, CSS나 SVG 내부에서 좌표를 이용해 필요한 부분만 표시하는 방식이다.

HTTP 요청이 많을 수록 느려지는 HTTP/1.x 프로토콜 사용시에 특히 중요하다.

HTTP/2 이상 + CDN 환경에서 병렬 요청이 빨라지면서 절대적이지는 않지만, 여전히 리소스 관리와 캐싱 효율성 측면에서 유효하다.

  1. Image Sprite (비트맵 스프라이트)

여러 개의 PNG/JPEG 아이콘을 하나의 큰 이미지 파일로 묶고, CSS background-position 으로 각 아이콘을 잘라서 표시한다.

장점

  • HTTP 요청 1회로 여러 아이콘을 불러옴 (요청 수 감소)
  • 모든 아이콘이 하나의 파일로 캐싱되어, 반복 참조 시 빠름
  • CSS만으로 제어 가능

단점

  • 아이콘 하나만 변경해도 전체 이미지 재배포 필요 (유지보수 어려움)
  • 고해상도 대응을 위해 별도 파일 필요
  • 비트맵 기반이라 색상 변경, 크기 조정이 불편
  1. SVG Sprite (벡터 스프라이트)

여러 SVG 아이콘을 하나의 <symbol> 세트로 묶고, 필요할 때 <use> 를 통해 인라인으로 삽입하는 방식

장점

  • HTTP 요청 감소
  • SVG이므로 해상도 무관, CSS로 색상 변경 용이
  • 심볼 기반으로 아이콘 추가/변경 시 유지보수 용이
  • Tree-shaking 및 inline build 가능

단점

  • IE 지원 문제
  • 빌드 파이프라인 설정 필요 (ex svg-sprite-loader)

HTTP/1.1 프로토콜에서는 동시 연결 수가 제한적이기 때문에 여러 개의 이미지를 각각 요청하면 네트워크 병목과 RTT 지연이 심했지만, HTTP/2 이상의 프로토콜에서는 Multiplexing , Header Compression 같은 기술들이 추가 되어 스프라이트의 요청 절감 효과가 줄어들었다.

0개의 댓글