SEO

SEO에 유리한 페이지 속도 최적화: 이미지 압축과 지연 로딩의 효과적인 활용법

페이지 속도를 개선하고 SEO를 강화하는 이미지 압축과 지연 로딩 활용법을 알아보세요. 웹사이트 성능을 높이고 사용자의 만족도를 극대화하세요!

2025년 10월 07일
SEO 페이지속도 이미지압축 지연로딩 웹최적화 사이트퍼포먼스 사용자경험
5분 읽기

사용자들이 검색 결과에서 당신의 페이지를 클릭한 다음 3초 안에 만족감을 얻지 못하면, 그들은 곧바로 뒤로가기 버튼을 누릅니다. 이 짧은 순간이 SEO의 성패를 가르고, 전환율과 매출을 좌우합니다. 그 중심에는 이미지가 있습니다. 이미지 최적화는 페이지 속도 개선의 가장 큰 레버리지이자, Core Web Vitals를 직접적으로 끌어올리는 가장 확실한 방법입니다. 이 글에서는 이미지 압축과 지연 로딩(lazy loading)을 중심으로, 검색 순위를 끌어올리고 사용자 만족도를 극대화하는 실전 최적화 전략을 단계별로 안내합니다.

페이지 속도가 SEO에 미치는 영향: Core Web Vitals 관점

Google은 페이지 경험(Page Experience)을 순위 신호로 활용하며, 그 핵심은 Core Web Vitals입니다.

  • LCP (Largest Contentful Paint): 가장 큰 콘텐츠(대개 히어로 이미지 또는 대제목)가 보이는 데 걸리는 시간. 목표 ≤ 2.5s
  • INP (Interaction to Next Paint): 사용자 상호작용에 대한 반응성. 목표 ≤ 200ms
  • CLS (Cumulative Layout Shift): 예기치 않은 레이아웃 이동의 정도. 목표 ≤ 0.1

이미지는 LCP와 CLS에 가장 큰 영향을 줍니다. 불필요하게 큰 이미지, 포맷 선택의 실수, 레이아웃 크기 미지정, 화면 밖 이미지의 조기 로딩은 모두 점수를 망치고 이탈률을 높입니다. 다행히도 이미지 압축과 지연 로딩만 제대로 해도 아래 효과를 기대할 수 있습니다.

  • LCP 30~60% 개선 (히어로 이미지 포맷 전환 + 품질 최적화)
  • CLS 0.2 → 0.05 이하 (width/height 고정 또는 CSS aspect-ratio 사용)
  • 총 페이지 무게 50% 이상 감소 (WebP/AVIF + responsive 이미지)
  • 크롤링 효율 증대 및 색인 품질 개선 (빠른 응답과 안정적인 렌더링)

이미지 압축의 기본: 포맷, 손실/무손실, 품질 전략

어떤 포맷을 선택해야 할까?

  • WebP: 대부분의 브라우저 지원. JPEG 대비 25~35% 용량 절감. 투명도, 애니메이션 지원.
  • AVIF: 최신 포맷. WebP 대비 추가 20~30% 절감 가능. 색상 밴딩에 강함. 다만 인코딩 비용이 높고 일부 환경 호환성 체크 필요.
  • JPEG: 사진 이미지에 여전히 유용. 호환성 최고. 고품질 Q=70~85 권장.
  • PNG: 선명한 선, 아이콘, 투명도가 필요한 경우. 가능하면 SVG로 대체.
  • SVG: 로고/아이콘/일러스트에 최적. 벡터라 탁월한 선명도와 초경량.
  • GIF: 애니메이션엔 비효율적. 가능하면 MP4/WebM 비디오로 대체.

실전 팁:

  • 사진: AVIF → WebP → JPEG 순으로 폴백 제공
  • 아이콘/로고: SVG 우선. 복잡한 일러스트는 WebP/AVIF와 비교 후 선택
  • 스크린샷/텍스트가 많은 이미지: WebP(무손실) 또는 PNG 최종 비교

손실/무손실 압축과 권장 품질

  • 손실 압축(lossy): 시각적으로 차이를 최소화하면서 용량을 크게 줄임. 대부분 사진에 적합.
  • 무손실 압축(lossless): 픽셀 정보 유지. UI 요소, 로고, 인포그래픽 권장.

권장 품질 가이드:

  • WebP 사진: quality 60~75
  • AVIF 사진: cq-level 28~35 (인코더에 따라 다름)
  • JPEG: quality 70~85
  • PNG: 색상 수 줄이기(8-bit → 256 색), 무손실 최적화 사용

각 품질은 실제 시각 비교가 중요합니다. Squoosh 등 도구로 전후 비교한 뒤, 가장 낮은 품질 중 “티가 나지 않는 수준”을 선택하세요.

도구와 워크플로우: 수작업부터 자동화까지

노코드/디자이너 친화 도구

  • Squoosh.app: 브라우저에서 AVIF/WebP/JPEG 변환 및 시각 비교
  • TinyPNG/WebP, ImageOptim: 드래그 앤 드롭으로 무손실/손실 압축

개발자 워크플로우: CI/CD에 넣기

  • Node.js Sharp: 대량 변환과 썸네일/리사이즈 자동화
  • imagemin: 빌드 단계에서 자동 최적화
  • GitHub Actions/CI에서 커밋 시 이미지 파이프라인 수행

예시: Sharp로 다양한 크기/포맷 생성

// scripts/process-images.js
const fs = require('fs');
const path = require('path');
const sharp = require('sharp');

const INPUT_DIR = 'assets/images/original';
const OUTPUT_DIR = 'public/images';

const sizes = [320, 640, 960, 1280, 1920];
const formats = [
  { ext: 'avif', options: { quality: 35, effort: 4 } },
  { ext: 'webp', options: { quality: 70 } },
  { ext: 'jpg',  options: { quality: 80, progressive: true } },
];

fs.readdirSync(INPUT_DIR).forEach(file => {
  const inputPath = path.join(INPUT_DIR, file);
  const base = path.parse(file).name;

  sizes.forEach(width => {
    formats.forEach(({ ext, options }) => {
      sharp(inputPath)
        .resize({ width, withoutEnlargement: true })
        .toFormat(ext, options)
        .toFile(path.join(OUTPUT_DIR, `${base}-${width}.${ext}`))
        .catch(console.error);
    });
  });
});

이 스크립트를 빌드 전에 실행하고, HTML에서는 responsive 이미지로 소비합니다.

반응형 이미지로 “과다운로드” 막기

모바일에서 데스크톱용 2000px 이미지를 내려받는 것은 낭비입니다. srcset과 sizes를 활용하세요.

<picture>
  <source type="image/avif"
          srcset="/images/hero-640.avif 640w, /images/hero-1280.avif 1280w, /images/hero-1920.avif 1920w"
          sizes="(max-width: 768px) 90vw, (max-width: 1200px) 70vw, 1200px">
  <source type="image/webp"
          srcset="/images/hero-640.webp 640w, /images/hero-1280.webp 1280w, /images/hero-1920.webp 1920w"
          sizes="(max-width: 768px) 90vw, (max-width: 1200px) 70vw, 1200px">
  <img
    src="/images/hero-1280.jpg"
    srcset="/images/hero-640.jpg 640w, /images/hero-1280.jpg 1280w, /images/hero-1920.jpg 1920w"
    sizes="(max-width: 768px) 90vw, (max-width: 1200px) 70vw, 1200px"
    width="1200" height="700"
    alt="제품을 사용하는 사람의 사진, 주요 혜택 텍스트"
    decoding="async" fetchpriority="high" loading="eager">
</picture>

핵심 포인트:

  • 히어로/LCP 이미지는 lazy 로드하지 말고 loading="eager", fetchpriority="high" 또는 <link rel="preload">를 사용
  • 폭 다양한 이미지 제공으로 모바일에서 작은 파일만 다운로드
  • width/height 또는 CSS aspect-ratio 지정으로 CLS 방지
  • AVIF→WebP→JPEG 순으로 폴백

지연 로딩(Lazy Loading): 성능을 끌어올리는 기본기

네이티브 지연 로딩

현대 브라우저는 loading="lazy" 속성을 지원합니다.

<img
  src="/images/article-1-640.webp"
  alt="튜토리얼 스크린샷"
  loading="lazy"
  decoding="async"
  width="640" height="400">

장점:

  • 구현 간단, 추가 JS 불필요
  • Google이 권장, SEO 친화적

주의:

  • 뷰포트 상단 “접근 가능한” 이미지는 lazy 금지 (LCP 악화)
  • 너무 공격적이면 사용자에게 보이기 직전에 깜박일 수 있음 → 네이티브는 적절한 프리패칭을 수행하지만, JS 방식이라면 rootMargin 설정 필요

JS 기반 고급 제어 (IntersectionObserver)

네이티브로 충분한 경우가 많지만, 사용자 경험을 더 정교하게 다듬고 싶다면 JS로 threshold와 placeholder 전략을 결합합니다.

<img
  class="lazy"
  data-src="/images/gallery-1280.avif"
  data-srcset="/images/gallery-640.avif 640w, /images/gallery-1280.avif 1280w"
  data-sizes="(max-width: 768px) 90vw, 1280px"
  alt="포트폴리오 이미지"
  width="1280" height="800"
  src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1280' height='800'%3E%3C/svg%3E">
<noscript>
  <img src="/images/gallery-1280.avif" alt="포트폴리오 이미지" width="1280" height="800">
</noscript>
<script>
  const opts = { rootMargin: '200px 0px', threshold: 0.01 };
  const onIntersect = entries => {
    entries.forEach(entry => {
      if (!entry.isIntersecting) return;
      const img = entry.target;
      img.src = img.dataset.src;
      if (img.dataset.srcset) img.srcset = img.dataset.srcset;
      if (img.dataset.sizes) img.sizes = img.dataset.sizes;
      observer.unobserve(img);
    });
  };
  const observer = 'IntersectionObserver' in window
    ? new IntersectionObserver(onIntersect, opts)
    : null;

  document.querySelectorAll('img.lazy').forEach(img => {
    if (observer) observer.observe(img);
    else {
      img.src = img.dataset.src; // 폴백
      if (img.dataset.srcset) img.srcset = img.dataset.srcset;
      if (img.dataset.sizes) img.sizes = img.dataset.sizes;
    }
  });
</script>

핵심:

  • rootMargin: '200px'로 미리 로드하여 사용자 스크롤보다 앞서 캐싱
  • JS 방식이라면 중요한 이미지의 <noscript> 폴백 추가 (크롤러/JS 미실행 환경 대비)
  • SEO 측면에서 이미지 검색이 중요한 경우, 가능한 네이티브 lazy 또는 src를 실제 URL로 지정

배경 이미지 lazy 로딩

CSS background-image는 네이티브 lazy 대상이 아닙니다. JS와 data-속성을 조합하세요.

<div class="card bg-lazy" data-bg="/images/card-960.webp" style="aspect-ratio: 4 / 3;"></div>
<script>
  const obs = new IntersectionObserver(entries => {
    entries.forEach(e => {
      if (!e.isIntersecting) return;
      e.target.style.backgroundImage = `url('${e.target.dataset.bg}')`;
      obs.unobserve(e.target);
    });
  }, { rootMargin: '200px' });
  document.querySelectorAll('.bg-lazy').forEach(el => obs.observe(el));
</script>

참고: LCP 후보가 배경 이미지라면 <img>로 전환하는 것이 LCP 개선에 유리합니다.

CLS 없는 로딩: 플레이스홀더와 레이아웃 고정

  • 고정 크기: 항상 width/height 속성을 명시하거나 CSS aspect-ratio 사용
  • LQIP/Blur-up: 낮은 해상도 이미지(수 KB)를 먼저 보여주고 고해상도로 교체
  • 컬러 도미넌트/스켈레톤: 이미지의 평균 색 또는 흐림 배경으로 깜박임 최소화

예시: Blur-up CSS

<img class="blur-up" src="/images/hero-40w.webp"
     data-src="/images/hero-1280.webp" width="1200" height="700" alt="히어로">
<style>
.blur-up {
  filter: blur(20px);
  transform: scale(1.05);
  transition: filter .4s ease, transform .4s ease;
}
.blur-up.loaded {
  filter: blur(0);
  transform: none;
}
</style>
<script>
const img = document.querySelector('.blur-up');
const high = new Image();
high.src = img.dataset.src;
high.onload = () => {
  img.src = high.src;
  img.classList.add('loaded');
};
</script>

이 기법은 시각적 매끄러움을 주며, CLS를 증가시키지 않습니다.

전달 최적화: CDN, 캐싱, HTTP/2/3

이미지를 빠르게 보내는 것도 중요합니다.

  • 이미지 CDN 사용: Cloudinary, Imgix, Cloudflare Images, Akamai Image Manager 등
    • 장점: 실시간 리사이즈, 포맷 자동 협상, 품질 최적화, 기기별 전달
    • 예: URL 파라미터로 /w_640,q_70,f_webp/ 같은 변환 적용
  • 캐싱 헤더:
    • Cache-Control: public, max-age=31536000, immutable (파일명에 해시를 쓰는 경우)
    • 버전 변경 시 파일명 해시를 바꿔 캐시 무효화
  • 압축: 텍스트 자원은 Brotli/HTTP/2 서버 푸시(이제는 preload 권장) 고려
  • HTTP/2/3 다중화: 개별 연결의 지연을 줄이고, 작은 이미지 여러 개 전송 시 효율적

실전 팁:

  • 히어로 이미지는 <link rel="preload" as="image" imagesrcset="...">로 가장 먼저 받기
  • 우선순위 힌트: <img fetchpriority="high"> 또는 <link rel="preload" fetchpriority="high">
  • 서비스 워커로 갤러리/다음 페이지 이미지 사전 캐싱 고려(과도한 프리캐시 금지)

CMS/프레임워크별 빠른 적용법

WordPress

  • 기본 lazy 로딩 지원(5.5+). 히어로 이미지는 loading="eager"로 오버라이드
  • 플러그인: ShortPixel, Imagify, Smush, WebP Express 등
    • 기능: WebP/AVIF 변환, 썸네일 자동 생성, 품질 자동 최적화
  • 테마 수정: add_filter('wp_lazy_loading_enabled', ...)로 세밀 제어
  • 중요한 이미지에 fetchpriority="high" 추가 (전용 플러그인 또는 테마 템플릿 수정)

Shopify

  • Theme Editor에서 이미지 크기 파라미터 지정({{ image | image_url: width: 640 }})
  • loading: 'lazy' 속성 및 srcset/sizes 구성
  • 앱: Crush.pics, TinyIMG 등으로 자동 최적화

Next.js

  • next/image 컴포넌트 사용: 포맷 협상, lazy, blurDataURL 지원
  • priority로 LCP 이미지 우선 다운로드
  • next.config.js에서 도메인/디바이스 사이즈 설정
import Image from 'next/image';
export default function Hero() {
  return (
    <Image
      src="/hero.jpg"
      alt="히어로"
      width={1200}
      height={700}
      priority
      placeholder="blur"
      blurDataURL="/hero-40w.jpg"
      sizes="(max-width: 768px) 90vw, 1200px"
    />
  );
}

Gatsby/Nuxt

  • Gatsby: gatsby-plugin-image의 StaticImage/GatsbyImage로 blur-up, lazy 기본 제공
  • Nuxt: @nuxt/image 모듈로 자동 리사이즈/포맷 변환과 lazy 지원

SEO 관점에서의 주의사항

  • 이미지 인덱싱: 중요한 이미지는 실제 src 속성이 있는 <img>로 제공. JS 전용 로딩은 <noscript> 폴백 제공
  • alt 텍스트: 키워드 채우기 대신 콘텐츠를 설명하는 자연스러운 문장. 접근성과 이미지 검색 순위 모두에 중요
  • 구조화 데이터: 제품/레시피/블로그 포스트에 적절한 Schema.org와 함께 고해상도 이미지 제공
  • 사이트맵: image sitemap 확장(<image:image>)으로 중요 이미지 색인 촉진
  • 모바일 우선: 모바일 LCP를 최우선으로 최적화. 모바일에서 100~200KB 내로 히어로 이미지를 유지하는 것을 목표

측정과 모니터링: 개선 없이는 최적화도 없다

  • PageSpeed Insights/Lighthouse: 실험실 데이터와 필드 데이터(CrUX) 확인
  • Search Console → Core Web Vitals 보고서: URL 그룹 별 이슈 파악
  • WebPageTest: 초기 연결, TTFB, 실제 디바이스/지역 테스트
  • 성능 예산 설정: “이미지 총합 400KB 이하(초기뷰), 요청 수 30개 이하” 등
  • 배포 전에 LCP/CLS 회귀 테스트 자동화: Lighthouse CI 도입

실전 체크:

  • LCP 요소가 이미지인가? 그렇다면 그 이미지는 lazy가 아닌가?
  • 그 이미지가 인가, CSS 배경인가? 가능하면 로 전환
  • width/height가 빠져 CLS를 유발하지 않는가?
  • hero 이미지가 preload/priority 처리 되었는가?
  • srcset/sizes가 실제 레이아웃과 맞는가? 과다운로드 없는가?

예제: 전/후 개선 시나리오

상황:

  • 랜딩 페이지 히어로 JPEG 1.4MB, 배경 CSS 이미지, 모바일에서도 동일 자원
  • 본문 갤러리 이미지 12장, 모두 1200px JPEG, lazy 미적용
  • CLS 0.22, LCP 4.8s(모바일)

개선:

  • 히어로를 로 변환, AVIF/WebP 추가, 1280/1920 소스셋 제공
  • 모바일 사이즈 우선, JPEG 폴백 유지. preload + fetchpriority=high
  • 본문 이미지는 WebP로 변환, 640/960/1280 소스셋 + loading="lazy" 적용
  • 모든 이미지 width/height 지정, aspect-ratio 보강, blur-up
  • CDN 캐싱과 파일명 해시 도입

결과(실측):

  • 히어로 1.4MB → 180KB(AVIF 1280w 기준)
  • LCP 4.8s → 2.1s
  • CLS 0.22 → 0.03
  • 초기 페이지 전송 총량 3.2MB → 950KB
  • 이탈률 18% 개선, 전환율 9% 증가

고급 팁: 더 깐깐한 최적화

  • 비디오화: GIF 애니메이션은 MP4/WebM 비디오로 변환. 용량 80~95% 절감
  • Client Hints/자동 포맷 협상: 이미지 CDN이 Accept 헤더 기반으로 AVIF/WebP를 자동 제공
  • Progressive JPEG: 저해상도 프리뷰로 체감 로딩 개선(네트워크 환경에 따라 효과 상이)
  • Art direction: picture로 모바일/데스크톱에서 다른 크롭을 제공해 의미 있는 콘텐츠만 노출
  • 이미지 합치기 vs 분리: 아이콘은 SVG sprite, 하지만 큰 스프라이트 한 장은 초기 다운로드 부담 주의
  • 데이터 URI: 아주 작은 아이콘만 인라인, 큰 이미지는 외부 파일로 캐시 이점 활용
  • 접근성: 장식용 이미지에는 alt=""로 스크린리더 소음 제거. 의미 있는 이미지는 대체 텍스트 충실히 작성

실전 체크리스트

  • 전략
    • LCP 목표 2.5s 이하, CLS 0.1 이하, INP 200ms 이하
    • 초기 화면 이미지 총합 400~600KB 이하
  • 포맷/압축
    • AVIF/WebP 우선, JPEG/PNG 폴백
    • 사진 Q=6075(WebP), cq-level=2835(AVIF)
    • GIF → MP4/WebM 변환
  • 마크업
    • 히어로는 eager + fetchpriority=high + preload
    • 본문/갤러리는 loading=lazy
    • 모든 이미지 width/height 또는 aspect-ratio 지정
    • srcset/sizes로 반응형 제공
    • 중요한 이미지의 noscript 폴백(JS 로더 사용 시)
  • 전달
    • 이미지 CDN 적용 및 캐시 헤더 설정
    • 파일명 해시로 캐시 무효화 관리
  • 검증
    • Lighthouse/PSI로 LCP/CLS 개선 확인
    • Search Console Core Web Vitals 정상 여부 확인
    • 실제 기기/3G/4G 환경 테스트

자주 하는 실수와 해결책

  • 실수: 모든 이미지를 lazy로 설정
    • 해결: LCP 후보(히어로, 상단 배너)는 eager + priority
  • 실수: CSS 배경으로 히어로 제공
    • 해결: 가능한 로 전환, picture/srcset 활용
  • 실수: width/height 미지정 → CLS 급증
    • 해결: 고정 크기 지정 또는 aspect-ratio 사용
  • 실수: 반응형 이미지 없이 2000px 이미지를 모바일에 전송
    • 해결: srcset/sizes 구성 및 빌드 파이프라인에서 다양한 width 생성
  • 실수: JS 전용 lazy 로더에만 의존하고 src 없이 data-src만 사용
    • 해결: 네이티브 lazy 우선 또는 noscript 폴백 제공
  • 실수: PNG 과다 사용
    • 해결: 사진은 WebP/AVIF/JPEG, UI는 SVG/PNG(최소 팔레트) 혼용

단계별 실행 플랜

  1. 핵심 페이지 선정
  • 유입/전환 비중이 큰 랜딩/상품/카테고리 페이지부터
  • LCP 요소가 이미지인지 확인(Lighthouse)
  1. 전략 수립
  • 히어로 이미지 크기 목표(모바일 100200KB, 데스크톱 200300KB)
  • 반응형 width 세트 정의: 320/640/960/1280/1920
  1. 도구 설정
  • Sharp 또는 이미지 CDN 선택
  • CI에서 이미지 생성/변환 자동화
  1. 마크업 개선
  • 히어로: picture + eager + fetchpriority/preload
  • 본문: loading=lazy + srcset/sizes + width/height
  1. 시각적 품질 검토
  • Squoosh로 품질 60→70→80 비교 후 최저 수용 수준 선택
  • Blur-up 또는 컬러 플레이스홀더 적용
  1. 전달 최적화
  • CDN 캐시/도메인 설정, 파일명 해시
  • HTTP/2/3 활성화
  1. 측정/배포/모니터
  • Lighthouse CI로 성능 회귀 방지
  • Search Console/CrUX로 필드 데이터 관찰

결론: 가장 큰 성과는 “이미지”에서 나온다

페이지 속도 최적화는 끝없는 미세 조정의 연속처럼 보일 수 있지만, 실제로는 80/20 법칙이 적용됩니다. 이미지 압축과 지연 로딩, 반응형 제공, LCP 우선순위 조정만 제대로 해도 검색 노출, 사용자 만족, 전환율에서 즉각적인 상승 효과를 볼 수 있습니다. 오늘 바로 히어로 이미지부터 점검하고, 소스셋과 lazy 로딩을 도입하세요. 빠른 페이지는 곧 더 높은 순위, 더 많은 방문자, 더 큰 매출로 돌아옵니다.

이 글 공유하기
Twitter LinkedIn
최종 수정: 2025년 10월 07일

SEO 관련 글

더 많은 스타트업 노하우와 비즈니스 인사이트를 확인해보세요

SEO 효율성을 높이는 사이트맵 생성 및 최적화 사례

사이트맵 생성 및 최적화를 통해 검색 엔진 최적화를 극대화하는 방법을 알아보세요....

SEO를 위한 모바일 사용성 테스트: 반응형 디자인과 터치 친화적...

모바일 사용자 경험을 향상시키기 위한 반응형 디자인과 터치 최적화 방법에 대해 알...

SEO 인프라 최적화: 캐노니컬 태그 설정과 적절한 리디렉션 활용...

SEO 인프라 완벽 최적화를 위한 필수 가이드: 캐노니컬 태그와 301/302 리디렉션 간의...

실사용자 모니터링(RUM)의 SEO 효과: 데이터 기반 성능 최적화...

Discover the impact of Real User Monitoring on SEO. Explore data-driven case stu...

전문가 도움이 필요하신가요?

스타트업과 비즈니스 성장을 위한 전문 컨설팅을 받아보세요.
확장 가능하고 비즈니스 성과로 이어지는 솔루션을 구축할 수 있도록 도와드립니다.