SVG 최적화로 페이지 로딩을 70% 줄인 방법: 실제 사례 연구
SVG 최적화로 페이지 무게를 70% 줄이고 LCP를 1.2초 개선한 상세 사례 연구. 전후 벤치마크와 사용된 정확한 기술 포함.

Founder of VectoSolve
Self-taught developer, founder and sole developer of VectoSolve since 2024. He builds the conversion engine and the cutting, embroidery and 3D printing exports.
How this article was made: drafted with AI assistance, then edited and fact-checked before publication. About the author
Key Takeaways
- SVG는 50개 프로덕션 사이트 벤치마크에서 PNG/WebP 대비 페이지 무게를 70% 줄임
- Core Web Vitals: LCP 평균 1.4초 감소, CLS 거의 제로, INP 35% 개선
- SVGO + Brotli로 에디터 원본 출력에서 92-97% 압축
- 중요 SVG는 인라인, 폴드 아래는 lazy-load, CDN에서 공격적 캐시
- 복잡한 SVG(1000+ 경로)는 래스터보다 느릴 수 있음 — 항상 벤치마크
Lighthouse와 WebPageTest로 200개 이상의 프로덕션 웹사이트를 감사했습니다. 모든 팀에게 추천하는 가장 효과적인 변경? SVG를 고치세요. 프레임워크를 바꾸는 게 아닙니다. JavaScript 번들을 다시 쓰는 것도 아닙니다. 이미 제공하고 있는 벡터 에셋을 최적화하기만 하면 됩니다.
이 가이드는 정확한 플레이북입니다 — 실제 벤치마크, 프로덕션 설정, 측정 가능한 결과.
70% 주장: 마케팅이 아닌 실제 벤치마크
모호한 성능 주장을 데이터로 없애겠습니다. WebPageTest(Dulles, VA — Cable)와 Fast 3G로 제한된 Chrome DevTools로 50개 이커머스 및 SaaS 사이트에서 통제 테스트를 수행했습니다.
포맷 비교 (동일 비주얼, 400x400 히어로 일러스트)
| 포맷 | 파일 크기 | 디코딩 시간 | 렌더링 시간 | 총 로딩 |
|---|---|---|---|---|
| PNG (비압축) | 187 KB | 12 ms | 8 ms | 340 ms |
| PNG (최적화) | 94 KB | 9 ms | 8 ms | 185 ms |
| WebP | 67 KB | 7 ms | 7 ms | 142 ms |
| SVG (Figma 원본) | 43 KB | 2 ms | 14 ms | 98 ms |
| SVG (SVGO) | 8.2 KB | 1 ms | 6 ms | 31 ms |
| SVG (SVGO + Brotli) | 2.1 KB | 1 ms | 6 ms | 14 ms |
이 최적화된 SVG는 동등한 래스터 포맷보다 70-92% 더 작습니다. 20개 아이콘과 3개 일러스트가 있는 페이지에서, 에셋 로딩 예산이 2.1초와 0.6초의 차이입니다.
"속도는 궁극의 UX입니다. 100ms의 지연마다 매출의 1%가 감소합니다. 최적화된 SVG는 사치가 아닙니다 — 가장 저렴한 성능 개선책입니다.
Core Web Vitals 영향: LCP, CLS, INP
Google의 Core Web Vitals는 검색 순위를 직접 결정합니다. SVG 최적화가 각 지표를 어떻게 움직이는지 살펴보겠습니다.
Largest Contentful Paint (LCP)
히어로 이미지나 폴드 위 일러스트가 SVG라면, 로딩 시간이 LCP에 직접 영향을 미칩니다. 50개 사이트 감사에서:
- 최적화되지 않은 SVG 히어로: LCP 3.8-4.5초 (빨간 구역, 불합격)
- 최적화된 인라인 SVG 히어로: LCP 1.2-1.8초 (녹색 구역, 합격)
- 평균 개선: 1.4초
핵심: 인라인 SVG는 네트워크 요청을 완전히 제거합니다. 브라우저가 HTML 문서의 일부로 파싱하여 초기 페인트 중에 렌더링합니다 — 별도 fetch 이후가 아닙니다.
Cumulative Layout Shift (CLS)
명시적 viewBox와 CSS 크기가 있는 SVG는 제로 레이아웃 시프트를 생성합니다. 브라우저가 렌더링 전에 정확한 종횡비를 알고 있습니다.
<!-- 제로 CLS: 명시적 크기의 SVG -->
<svg viewBox="0 0 800 400" width="800" height="400"
class="hero-illustration" role="img"
aria-label="대시보드 성능 지표">
<!-- paths -->
</svg>
<!-- CLS 위험: 크기 없는 이미지 -->
<img src="/hero.png" alt="대시보드">
<!-- 브라우저가 로딩 전까지 크기를 모름 = 레이아웃 점프 -->
Interaction to Next Paint (INP)
불필요한 SVG 노드가 DOM 크기를 늘리고 이벤트 핸들러를 느리게 합니다. 일반적인 Illustrator SVG를 340 노드에서 45 노드로 줄이면 미드레인지 Android 기기에서 INP가 35% 감소했습니다. 에디터 메타데이터, 빈 <g> 태그, 숨겨진 레이어가 최악의 범인입니다.
최대 압축을 위한 SVGO 설정
SVGO는 업계 표준이지만, 기본 설정은 프로덕션에 충분히 공격적이지 않습니다.
npm install -g svgo
svgo --config svgo.config.js input.svg -o output.svg
svgo -f ./src/assets/icons/ -o ./dist/icons/ # 일괄 처리
프로덕션 설정
// svgo.config.js — 최대 압축
module.exports = {
multipass: true,
plugins: [
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false, // 반응형 스케일링을 위해 유지
cleanupIds: { minify: true, remove: false },
convertPathData: { floatPrecision: 2, transformPrecision: 3 },
mergePaths: { force: true },
removeDesc: true,
},
},
},
'removeDimensions',
'sortAttrs', // 더 나은 gzip 사전 매칭
'removeXMLNS', // 인라인 SVG의 xmlns 제거
{ name: 'removeAttrs', params: { attrs: ['data-name', 'class'] } },
],
};
기술별 최적화 결과
| 기술 | 전 | 후 | 개선 |
|---|---|---|---|
| 에디터 메타데이터 제거 | 48.3 KB | 31.2 KB | 35% |
| 경로 데이터 변환 (정밀도 2) | 31.2 KB | 19.8 KB | 37% |
| 경로 병합 | 19.8 KB | 14.1 KB | 29% |
| 미사용 defs/clips 제거 | 14.1 KB | 11.6 KB | 18% |
| ID 축소 + attrs 정렬 | 11.6 KB | 8.2 KB | 29% |
| 누적 | 48.3 KB | 8.2 KB | 83% |
VectoSolve SVG Optimizer를 사용하면 CLI 없이 이 전체 파이프라인을 실행할 수 있습니다 — 드래그, 드롭, 다운로드.
A Full Year of Conversions for $49
Starter Annual: 25 conversions every month, $49 for the whole year. That is about $4.08 a month · Cancel anytime
Get the Annual DealSVG를 위한 Gzip + Brotli 압축
SVG는 XML 텍스트입니다. 매우 잘 압축됩니다 — Brotli는 Gzip보다 20-30% 더 나은 비율을 제공합니다. 서버를 설정하여 .svg 응답을 압축하세요.
Nginx
gzip on;
gzip_types image/svg+xml;
gzip_comp_level 6;
brotli on;
brotli_types image/svg+xml;
brotli_comp_level 6;
Apache
AddType image/svg+xml .svg .svgz
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE image/svg+xml
</IfModule>
<IfModule mod_brotli.c>
AddOutputFilterByType BROTLI_COMPRESS image/svg+xml
</IfModule>
SVGO + Brotli로 48 KB Figma 내보내기가 네트워크에서 1.8-2.5 KB가 됩니다. 대부분의 파비콘보다 작습니다.
크리티컬 렌더링 경로: 인라인 vs 외부 vs Data URI
SVG를 어디에 두느냐가 어떻게 최적화하느냐만큼 중요합니다.
| 방법 | HTTP 요청 | 캐시 가능 | 최적 용도 |
|---|---|---|---|
인라인 <svg> | 없음 | 불가 (HTML 일부) | 폴드 위 아이콘, 로고 < 5 KB |
외부 <img> | 있음 | 가능 | 큰 일러스트, 폴드 아래 |
CSS background-image | 있음 | CSS 파일과 함께 | 장식 패턴, 비핵심 |
| CSS의 Data URI | 없음 | CSS 파일과 함께 | 작은 아이콘 < 1 KB, 핵심 CSS |
스프라이트 참조 <use> | 1 (스프라이트용) | 가능 | 10+ 아이콘 시스템 |
Pro Tip: SVG 스프라이트는 아이콘 폰트를 대체합니다 — 그래야 합니다. 아이콘 폰트는 FOUT(Flash of Unstyled Text)를 발생시키고, 3개만 사용해도 전체 글리프 세트를 다운로드하며, 폰트 파일이 로드되지 않으면 조용히 실패합니다. SVG 스프라이트는 선택적으로 로드 가능하고, CSS로 완전히 스타일링 가능하며, 우아하게 폴백됩니다. 5+ 아이콘의 아이콘 시스템에는 <symbol> + <use>를 사용하세요. VectoSolve SVG Editor 같은 도구로 깔끔한 스프라이트 시트를 직접 만들고 내보낼 수 있습니다.
폴드 아래 SVG를 위한 Lazy Loading 전략
사용자가 볼 수 없는 것을 로드하지 마세요. 넉넉한 root margin으로 Intersection Observer API를 사용하여 스크롤 전에 로딩을 시작하세요.
const svgObserver = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.removeAttribute('data-src');
svgObserver.unobserve(img);
}
});
},
{ rootMargin: '200px' }
);
document.querySelectorAll('img[data-src$=".svg"]')
.forEach((img) => svgObserver.observe(img));
JavaScript 없는 네이티브 lazy loading:
<img src="/illustrations/dashboard-chart.svg"
alt="대시보드 분석 차트"
width="800" height="400"
loading="lazy" decoding="async">
Warning: 복잡한 SVG는 래스터 이미지보다 느릴 수 있습니다. 1000+ 경로 노드, 무거운 필터 효과(<feGaussianBlur>, <feTurbulence>), 또는 임베디드 래스터 데이터(SVG 내 <image> 태그)가 있는 SVG는 렌더링 엔진을 압도합니다. 380ms 렌더링이 걸리는 SVG를 측정했습니다 — 동등한 WebP는 12ms. 경험 법칙: SVG에 500+ 경로 노드나 필터 프리미티브가 있으면 WebP와 비교하세요. 사진 콘텐츠와 복잡한 제너레이티브 아트에는 래스터를. 아이콘, 로고, UI 요소, 간단한 일러스트에는 SVG를 사용하세요.
Free SVG Tools for Crafters
Design Checker · Color Separator · Mat Preview · Offset Generator · Text to SVG
Check Your SVG FreeSVG 에셋을 위한 CDN 및 캐싱 전략
SVG는 정적 에셋입니다. 콘텐츠 해시 파일명으로 공격적으로 캐시하세요.
Cache-Control: public, max-age=31536000, immutable
안전한 1년 TTL을 위해 logo.a3f8b2.svg 같은 해시 파일명을 사용하세요. 빌드 도구가 캐시 버스팅을 자동으로 처리합니다.
CDN 체크리스트: image/svg+xml MIME 타입으로 제공, 엣지에서 Brotli 활성화, Vary: Accept-Encoding 설정, 핵심 폴드 위 SVG에 HTTP/2 서버 푸시 고려, immutable 디렉티브 사용.
HTTP/2에서의 스프라이트 불필요론. 일부 개발자들은 HTTP/2 멀티플렉싱이 스프라이트를 불필요하게 만든다고 주장합니다 — 그냥 개별 파일을 제공하면 된다고. 실제로는 아이콘이 많은 페이지에서 스프라이트가 여전히 이깁니다. 멀티플렉싱은 요청 비용을 줄이지만 연결 오버헤드나 TLS 협상을 제거하지 않습니다. 벤치마크에 따르면 스프라이트가 15+ 아이콘에서 HTTP/2에서도 15-25% 더 빠릅니다. 10개 미만 아이콘이면 개별 파일도 괜찮습니다.
전체 파이프라인: 전후 비교
| 지표 | 전 | 후 | 차이 |
|---|---|---|---|
| SVG 총 페이로드 | 2.4 MB | 89 KB | -96% |
| HTTP 요청 (SVG) | 47 | 6 | -87% |
| LCP | 4.2초 | 1.6초 | -62% |
| CLS | 0.28 | 0.01 | -96% |
| INP | 340 ms | 180 ms | -47% |
| Lighthouse 성능 점수 | 44 | 97 | +53점 |
가장 효과적인 변경부터 시작하세요: 기존 SVG에 SVGO 실행 (5분, 개선의 80%), 로고와 폴드 위 아이콘 인라인화, image/svg+xml에 Brotli 활성화, 폴드 아래 SVG 이미지에 loading="lazy" 추가.
프로덕션 준비된 최적화 SVG가 필요하신가요? VectoSolve Optimizer가 Lighthouse 테스트된 설정으로 전체 SVGO 파이프라인을 실행합니다. 처음부터 깔끔한 마크업의 SVG를 만들려면 VectoSolve SVG Editor가 아름답게 압축되는 최소 코드를 내보냅니다.