Blog
Figma에서 SVG로 export했는데도 용량이 컸던 이유
서론#
Figma에서 아이콘이나 일러스트를 받을 때
SVG로 export하면 당연히 벡터 이미지라고 생각하기 쉽다.
나도 처음에는 그렇게 생각했다.
그런데 프로젝트에서 Figma에서 export한 SVG를 사용하던 중,
네트워크 탭에서 특정 이미지 파일의 용량이 생각보다 크게 잡히는 것을 확인했다.
SVG인데 왜 이렇게 용량이 크지?
라는 의문이 들었고,
실제 SVG 파일을 열어보니 원인을 확인할 수 있었다.
SVG 파일 안에 path가 아니라
image 태그가 들어가 있었다.
이 글은
Figma에서 SVG로 export했지만 실제로는 이미지가 포함되어 있던 문제와,
이를 WebP로 변환해 용량을 줄인 과정을 기록한다.
문제였던 구조#
문제의 시작은 단순했다.
Figma에서 SVG로 export한 파일을 프로젝트에 추가했고,
브라우저에서 확인했을 때 화면도 정상적으로 보였다.
하지만 네트워크 탭을 확인해보니
SVG 파일이라고 보기에는 용량이 너무 컸다.
일반적으로 SVG는
도형, 선, 색상 같은 정보를 XML 형태로 저장한다.
그래서 단순한 아이콘이나 일러스트라면
용량이 비교적 작게 유지되는 경우가 많다.
하지만 이번 파일은 그렇지 않았다.
파일을 열어보니 내부에 이런 코드가 있었다.
<svg
width="77"
height="21"
viewBox="0 0 77 21"
xmlns="http://www.w3.org/2000/svg"
>
<image
width="595"
height="194"
preserveAspectRatio="none"
xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAlMAAADCCAYAAABt5Ecn..."
/>
</svg>
여기서 중요한 부분은 image 태그다.
<image xlink:href="data:image/png;base64,..." />
즉,
확장자는 .svg였지만
실제로는 SVG 안에 PNG 이미지 데이터가 base64로 들어가 있는 구조였다.
SVG라고 해서 항상 벡터는 아니다#
이번 문제에서 가장 헷갈렸던 부분은 이 지점이었다.
SVG 파일이라고 해서
항상 path 기반의 벡터 이미지인 것은 아니다.
SVG는 내부에 image 태그를 포함할 수 있다.
이 경우 SVG는 벡터 도형을 표현하는 파일이라기보다,
이미지를 감싸고 있는 컨테이너에 가까워진다.
즉, 다음 두 파일은 모두 확장자는 SVG일 수 있다.
path,rect,circle등으로 구성된 벡터 SVGimage태그로 PNG나 JPEG 같은 비트맵을 포함한 SVG
겉으로 보기에는 둘 다 SVG지만,
성격은 완전히 다르다.
원인으로 보였던 부분#
정확한 제작 과정을 모두 확인한 것은 아니지만,
원인은 Figma 안에서 해당 그래픽이
SVG path로 만들어진 것이 아니라 이미지 형태로 들어가 있었기 때문으로 보였다.
이 상태에서 SVG로 export하면
Figma는 이미지를 벡터 path로 변환해주는 것이 아니라,
이미지를 SVG 내부의 image 태그로 포함한다.
그래서 결과적으로
SVG 파일을 사용하고 있지만
실제 용량은 포함된 이미지의 영향을 그대로 받게 된다.
해결 방법#
가장 좋은 해결 방법은
디자인 리소스를 처음부터 path 기반의 SVG로 만드는 것이다.
그렇게 되면 SVG의 장점을 그대로 사용할 수 있다.
- 해상도에 덜 의존함
- 크기를 키워도 깨지지 않음
- 파일 용량이 작아질 가능성이 높음
- CSS나 속성으로 일부 제어하기 쉬움
하지만 모든 그래픽을 path로 다시 만드는 것이
항상 가능한 것은 아니다.
이번에는 현실적인 대안으로
SVG 안에 들어 있던 이미지를 WebP로 변환했다.
그리고 실제 사용 환경에서 선명도가 너무 떨어지지 않도록
2배 크기로 확대한 WebP도 함께 사용했다.
왜 WebP로 바꿨는가#
기존 SVG는 이미 내부에 비트맵 이미지를 포함하고 있었다.
즉,
이미 벡터의 장점을 제대로 활용하지 못하는 상태였다.
이런 경우에는
확장자만 SVG로 유지하는 것보다
차라리 이미지 파일로 보고 최적화하는 편이 더 명확하다.
WebP는 PNG나 JPEG보다
같은 품질 대비 용량을 줄이기 좋은 포맷이다.
그래서 이번에는
기존 SVG를 WebP로 변환하고,
필요한 경우 2배 크기 이미지를 사용해 화면 품질을 보완했다.
최적화 결과#
실제로 변환 후 용량은 크게 줄었다.
| 파일 | 원본 SVG | WebP 1x | WebP 2x |
|---|---|---|---|
| service-second-item-01 | 1.7MB | 9.7KB | 24.9KB |
| service-second-item-02 | 1.0MB | 10.3KB | 24.1KB |
| service-third-phone-layout | 2.7MB | 2.8KB | 6.8KB |
특히 service-third-phone-layout 파일은
원본 SVG가 2.7MB였지만,
WebP 2x 기준으로도 6.8KB까지 줄었다.
이 정도 차이라면
네트워크 비용과 초기 로딩 관점에서
WebP로 변환하는 쪽이 훨씬 낫다고 판단했다.
개선된 점#
1. 파일 용량 감소#
가장 직접적인 개선은 파일 용량이었다.
기존에는 SVG 확장자를 사용하고 있었지만,
실제로는 내부에 이미지가 포함되어 있어 용량이 컸다.
WebP로 변환하면서
각 파일의 용량이 크게 줄었고,
불필요하게 큰 리소스를 내려받는 문제를 줄일 수 있었다.
2. 리소스 성격이 명확해짐#
기존 파일은 이름과 확장자만 보면 SVG였지만,
실제로는 이미지에 가까운 파일이었다.
이런 상태는 유지보수할 때 혼란을 만든다.
WebP로 변환한 뒤에는
이 리소스가 벡터가 아니라 이미지라는 점이 더 명확해졌다.
즉,
파일 형식과 실제 사용 방식이 맞아졌다.
3. 현실적인 품질 보완#
물론 WebP로 바꾼다고 해서
비트맵 이미지의 한계가 사라지는 것은 아니다.
확대하면 여전히 깨질 수 있다.
하지만 기존 SVG도 내부에 이미지가 들어간 구조였기 때문에,
확대 시 깨질 수 있다는 문제는 이미 존재하고 있었다.
그래서 이번에는
WebP 2x 이미지를 사용해
용량을 크게 늘리지 않으면서도 화면 품질을 보완했다.
주의할 점#
WebP 변환이 항상 정답은 아니다.
가장 좋은 방법은
가능하다면 디자인 리소스를 path 기반 SVG로 정리하는 것이다.
SVG가 진짜 벡터로 구성되어 있다면,
WebP로 바꾸는 것보다 SVG를 유지하는 편이 더 적절할 수 있다.
하지만 SVG 내부에 image 태그가 들어가 있고,
용량이 크며,
실제로 벡터의 장점을 활용하지 못하는 상황이라면
이미지 최적화 관점에서 다시 판단해야 한다.
이때 WebP 변환은
현실적인 대안이 될 수 있다.
실제 적용 PR#
이번 최적화는 아래 PR에서 진행했다.
이 PR에서는
Figma에서 SVG로 export된 리소스 중
내부에 이미지가 포함되어 있던 파일들을 WebP로 변환했다.
결과적으로
파일 용량을 크게 줄이면서도
화면에서 필요한 품질은 유지할 수 있었다.
정리#
Figma에서 SVG로 export했다고 해서
항상 가벼운 벡터 SVG가 만들어지는 것은 아니다.
SVG 내부에 image 태그가 들어가 있다면,
그 파일은 사실상 이미지를 감싼 SVG에 가깝다.
이 경우에는
SVG라는 확장자만 보고 안심하기보다,
실제 파일 내부 구조와 네트워크 용량을 함께 확인해야 한다.
가장 좋은 해결은
path 기반 SVG로 만드는 것이다.
하지만 그게 어렵다면,
WebP로 변환하고 필요한 경우 2배 크기로 보완하는 방식도
충분히 현실적인 선택이 될 수 있다.