Sunday Dec 4, 2022
-6°C
Broken clouds
18
October, 2022
NEWS TODAY
오리지널

Inline SVG Optimization

SVG일러스트레이터피그마
POST STATUS
VIEWS :
COMMENTS :
guest
0 Comments
Inline Feedbacks
View all comments

Inline SVG 최적화를 위한 방법

Inline SVG는 문서나 컴포넌트의 코드에 직접 삽입할 수 있어 별도의 파일로 관리하는 것 보다 어셋 관리가 용이하다.
반대로, 벡터 노드가 많아질수록 좌표값이 길어져 코드 가독성이 떨어지는 단점도 있다.

이번 글에서는 Inline SVG를 효율적으로 사용하는 방법에 대해 알아보고, 일러스트레이터와 피그마를 통한 활용법도 함께 다루고자 한다.

벡터 노드의 최적화

벡터 노드는 곧 앵커 포인트(Anchor Point)를 의미하며, 아트웍의 조형을 해치지 않는 최소한의 노드 갯수만 확보하는 것이 목표다.

잘 정리된 Inline SVG 코드는 스타일링이 편하고 코드 블럭의 문맥 훼손을 최소화하며, 어셋 파일 관리가 필요없어진다.

다만, 애초에 워낙 노드가 많고 복잡한 아트웍이라면 위의 장점들이 대부분 사라지고, 캐싱도 되지 않아 코드가 매번 렌더링 되므로 별도의 파일로 관리하는 편이 낫다.

아트웍 준비 - Illustrator

인터넷상에 많이 알려진 아이콘들은 대부분 노드 최적화가 잘 되어 있으므로 직접 만드는 경우를 통해 살펴본다.

먼저 일러스트레이터에서 Stroke로만 이루어진 아트웍을 하나 만들고, Object > Path > Outline Stroke 까지 적용한다.

아래 예제에서 하트는 단 2개의 포인트면 만들 수 있는데, Outline Stroke가 적용되면 대략 18개 정도의 포인트가 생긴다.

브라우저뿐만 아니라 그래픽 에디터에서도 동일한 비율의 테두리 두께를 가지기 위해 Outline Stroke를 실행하였다.

코드 검사 - Figma & Illustrator

피그마에서는 SVG로 만들고자 하는 요소를 마우스 우클릭 후 Copy as SVG로 클립보드에 저장하여 메모장이나 기타 텍스트 에디터에 붙여 별도의 Export 없이 확인할 수 있다.

일러스트레이터는 Layer 팔레트에서 해당 아트웍을 선택하고 키보드의 복사/붙이기 단축키로 동일하게 수행할 수 있다.

이렇게 클립보드에 저장된 코드는 일러스트레이터와 피그마 양쪽 캔버스 모두에서 그대로 붙여넣기할 수 있다.

노드 정리 #1 - Figma & Illustrator

불필요한 포인트를 제거해서 노드를 정리한다. 피그마에서는 Object 편집 상태에서 Pen 툴을 선택하고, Alt(Option)키를 누른 상태로 앵커 포인트를 클릭하면 최대한 조형을 유지한채로 삭제한다.

다만, 피그마는 본래 프로토타이핑과 인터페이스 디자인을을 위한 앱이므로 동일한 아트웍이라고해도 일러스트레이터에서 포인트를 삭제할 때보다는 연산이 좋지 않다.

피그마에서는 포인트가 제거될 때 조형이 쉽게 무너지는 경우가 있다. 적당히 정리하고, 되도록 최적화는 일러스트레이터에서 마친 후 복사/붙여넣기로 가져오는 편이 좋다.

Move 툴 상태로 제거하고자 하는 포인트를 선택하고, 피그마 상단 Main Menu > Vector > Delete and heal selection을 적용해도 같은 효과다. 단축키는 Shift + Delete.

일러스트레이터에서는 단축키 마이너스(-)Delete Anchor Point Tool로 변경한 후, Shift 키를 누른 상태로 포인트를 클릭한다.

Window > Toolbars > Advanced를 선택하면 툴바가 확장되는데,  Pen툴 아이콘을 길게 누르고 있으면 Delete Anchor Point Tool을 볼 수 있다.

어떤 포인트를 먼저 제거하느냐에 따라 결과가 달라지므로, 조형이 무너질 때 마다 Undo로 되돌려 다른 포인트 먼저 제거해가며 정리한다.

예제의 하트는 18개의 포인트에서 8개까지 줄일 수 있다.

이 단계에서 포인트를 과도하게 줄이기 위해 앵커 포인트의 핸들(포인트 좌우에 생기는 조정자)을 사용해 무너진 조형을 맞추기 보다는, 다음 단계에서 알아 볼 Simplify를 먼저 고려해 본다.

노드 정리 #2 - Illustrator

Pen 툴을 이용한 노드 정리는 피그마와 일러스트레이터 모두 사용할 수 있다.

이번에는 일러스트레이터에서만 쓸 수 있는 Simplify와 병행해서 노드를 더욱 효과적으로 정리해 본다. 피그마에도 Simplify라는 플러그인이 있지만 용도가 완전히 다르니 고려하지 않는다.

일단 노드를 정리하기 이전인 Outline Stroke가 적용된 단계까지 Undo 한다.

정리할 아트웍을 전체 선택하고 일러스트레이터 메뉴의 Object > Path > Simplify을 실행한다. 이후 나타나는 작은 콘트롤러에서 가장 우측 아이콘을 눌러 세부 설정화면을 연다.

PreviewShow Original Path 체크박스는 실시간으로 노드의 상황을 확인할 수 있으므로 체크한다. 삭제될 포인트와 재설정 될 경로는 다른 색으로 표시해 주므로 명령 실행 전후를 쉽게 비교할 수 있다.

그리고 Simplify CurveCorner Point Angle Threshold 2개의 슬라이더를 조정해서 최적의 노드를 찾으면 되는데, 이미지의 푸른 색 박스로 표시해 놓은 Original 값과 New 값을 비교하면 된다.

  • 두 슬라이더 모두 가장 오른편으로 밀어 최대값인 상태에서 시작한다.
  • 먼저 Corner Point Angle Threshold 슬라이더를 조정하여 조형이 무너지지 않는 선에서 New 값이 가장 작은 각도를 설정한다.
  • Simplify Curve 슬라이더를 조정하여 조형이 무너지지 않는 선에서 New 값이 가장 작은 각도를 설정한다.

Simplify
Object > Path > Simplify

마지막으로 Delete Anchor Point Tool로 최종 정리를 해준다. 이제 하트는 총 4개의 포인트만 가지게 되었다. 

Simplify 이후에는 각 포인트의 핸들러가 재설정되어, 포인트를 제거해도 조형이 잘 무너지지 않는 장점이 있다.
따라서 Simlify Curve 슬라이더는 최대한 Maximum 값으로 두고, Delete Anchor Point Tool 툴로 마무리 하는것이 좋다.

상용 일러스트레이터 플러그인 Astute Graphics의 Smart Remove Brush 툴이 매우 편리하다.
하지만 실제로 사용해 보면 일러스트레이터 코어 기능인 Simplify + Delete Anchor Point Tool 조합의 성능에는 미치지 못한다.

각 노드 정리 방법에 따른 최종 path 코드의 변화는 다음과 같다.

				
					// 노드 정리 안함
<path d="M135.416,241.152l-2.913-1.082C42.472,206.602,5.314,142.31,.561,93.301-2.863,58.004,9.531,28.094,33.713,13.291c15.421-9.438,48.777-20.117,101.28,11.672C184.493-9.361,217.162-.919,232.448,7.397c24.193,13.162,37.444,42.071,35.446,77.331-1.624,28.658-13.459,58.747-33.324,84.725-22.848,29.877-56.139,54.267-96.274,70.532l-2.88,1.167ZM69.664,19.615c-10.304,0-19.597,2.425-27.597,7.322-18.836,11.53-28.399,35.761-25.581,64.819,4.236,43.671,37.682,101.052,118.68,132.214,82.104-34.355,114.181-94.733,116.755-140.147,1.639-28.925-8.499-52.241-27.119-62.371-21.433-11.662-51.547-4.706-84.792,19.579l-4.418,3.228-4.61-2.948c-22.493-14.383-43.428-21.695-61.318-21.695Z"/>

// Pen 툴로만 정리
<path d="M135.41,241.162S10.976,200.741,.555,93.312C-6.217,23.496,49.555-26.754,134.987,24.973c80.869-56.076,136.836-9.675,132.901,59.765-6.268,110.613-132.479,156.424-132.479,156.424ZM42.061,26.948C-6.986,56.97,7.337,174.803,135.16,223.981,264.098,170.028,273.906,48.179,224.796,21.462c-37.513-20.408-89.21,22.807-89.21,22.807,0,0-55.317-40.708-93.524-17.321Z"/>


// Simplify와 Pen 툴 병행
<path d="M135.111,241.072C-63.081,172.597-25.916-68.147,134.689,24.883c152.715-102.39,199.826,139.357,.423,216.189Zm-.25-17.182c169.854-66.397,140.841-284.814,.425-179.711-139.877-95.204-177.852,111.45-.425,179.711Z"/>
				
			

내보내기

노드 정리가 되었다면 최종 결과물로 내보내기(Export) 위한 작업을 한다.

Inline SVG는 파일 형태로 저장할 필요가 없으니 Export를 진행할 필요가 없어보이지만, 일러스트레이터에서는 Copy(Control + C) 명령으로 코드만 복사하는 경우에도 Export 설정을 참조한다.

좌표에서 소수점 제거 - Figma & Illustrator

SVG는 스크린만을 위한 이미지 포맷이 아니다.

스크린보다 더욱 조밀한 망점을 가진 인쇄물에서 소수점은 더욱 정확한 표현을 제공하는데, 이 소수점이 스크린에서는 의도치 않은 두께로 표현되거나 경계가 뭉개지는 현상이 발생한다.

이에 대한 자세한 내용은 어도비 일러스트레이터에서 혼란요소 해결하기에서 다뤘다.

따라서 인쇄물이 아닌 웹, 앱등의 스크린 리더 환경이라면 소숫점을 없애거나 최소화하는 것이 좋다.

우선, 피그마에서는 내부적으로 소수점을 이용하지만 Copy 혹은 Export 시 코드에는 반영하지 않으므로 이 부분에 대해 신경 쓸 필요가 없다. 애초에 인쇄물을 위한 툴이 아니기 때문이다.

Transform and Artboard

일러스트레이터에서는 원하는 요소를 전체선택 한다.
레이어 팔레트에서 레이어만 선택해서는 안된다. 반드시 레이어 팔레트 가장 오른쪽에 있는 동그라미 아이콘을 클릭해서 전체 선택을 해주어야 한다.

그리고 Window > Transform에서 x, y, width, height 값에서 소수점을 모두 제거한다.
이 상태에서 복사/붙이기로 텍스트 에디터에서 확인하면 SVG 태그의 width, height, viewbox 어트리뷰트의 값들이 정수로 입력되어 있다.

다만, 이 상태에서 파일로 내보내기를 하면 아직 Artboard의 크기가 조정되지 않았기 때문에 viewbox 어트리뷰트에 다시 소수점이 들어갈 수 있으니 아트보드도 현재 아트웍의 크기에 맞게 조정한다.

Window > Artboard 창에서 아트보드 아이콘을 클릭하거나, 툴바의 아트보드 아이콘을 더블클릭한다.

Preset 리스트에서 Fit to Artwork Bounds 혹은 Fit to Selected Art를 선택하고 OK 버튼을 누르면 아트보드의 좌표가 소수점 없이 아트웍과 동일해진다.

이 상태에서 내보내기(Export) 하게되면 코드에 정상적으로 반영된다.

소수점 정밀도 - Figma & Illustrator

SVG는 좌표의 세부 경로를 소수점까지 제공하는데, 편집툴마다 다르지만 일러스트레이터의 경우 소수점 이하 자릿수 1부터 7까지 지정하며, 피그마는 3으로 고정이다.

정밀도가 높다는 것은 그만큼 많은 소수점 자리수를 사용한다는 것이고, 아트웍이 여러 상황에서 보다 정확하게 표현된다는 의미다.

다만 아트웍 마다 최소 정밀도는 모두 다르고, 그 이상의 정밀도는 파일 크기가 커지는 것 외에는 유의미한 이점이 없다.

따라서 가장 적은 양의 코드를 생성하면서도 시각적으로 손실이 없는 소수점 정밀도를 찾는 것이 관건이다.

Export Dialog Box

소수점 정밀도는 보통 SVG로 Export 하는 다이얼로그 박스에 위치하며 피그마는 정밀도 3으로 고정이므로 설정이 없다. 후술할 SVGMO 사이트에서 조정할 수 있다.

일러스트레이터는 SVG로 Export 하는 다이얼로그가 3개나 되면서 서로 설정 상태가 공유되지 않아 사용자를 매우 혼란스럽게 만든다.

  1. File > Save As에서 파일형식을 SVG로 변경하고 저장 버튼을 누르면 다이얼로그가 나타난다.
    하단의 More Options를 클릭하면 Decimal Places가 소수점 정밀도다.

  2. File > Export > Export As에서 파일형식을 SVG로 변경하고 Export 버튼을 클릭하면 다이얼로그가 나타난다.
    Decimal이 소수점 정밀도다. 모든 설정은 OK 버튼을 눌러야 저장된다.

  3. Export 하고자 하는 아트웍을 전체선택 한 후, File > Export Selection을 선택하면 나타나는 다이얼로그 박스에서 우측 Formats 부분의 톱니바퀴 아이콘을 클릭한다.
    좌측 사이드바에서 SVG를 선택하면 Dicimal을 볼 수 있다.

 

아트웍을 선택해서 Control + C로 Copy 할 경우 2번의 Export As의 다이얼로그 박스 설정을 따르므로 여기서 변경한 Deciaml 값이 복사된다. 기본값으로 3을 입력하고 OK 버튼을 누른다.

Inline SVG를 위한 소수점 정밀도

보통 소수점 정밀도가 3이면 두께 1px의 얇은 실선을 가진 요소도 크기에 관계없이 안정적인 시청각 정보를 제공한다.
원론적으로는 정밀도가 낮아질수록 유실되는 경로 정보도 많아지므로 조형은 왜곡되고, 정밀도가 높을수록 정확히 표현된다.

하지만 실제로 눈에 보여지는 결과는 아트웍마다 모두 다르다.

대부분의 아트웍 요소는 정밀도 3 이상부터는 시각적으로 아무런 변화가 없고 데이터만 많아지며, 어떤 경우는 정밀도 3보다 1이 더 안정적인 라인을 표현하기도 한다 (예를들면 1px 실선을 가진 350 x 350 크기의 원 요소).

평균적으로 정밀도 3이 데이터의 양적 측면과 시청각 정보 사이의 균형이 좋으니 SVG를 인라인이 아닌 파일로 저장할 때는 3 혹은, 파일 크기야 커지겠지만 7까지 사용해도 상관없다.

아트웍의 크기가 클수록, 속(Fill)이 찬 조형일수록, 테두리 두께가 두꺼울수록(최소 1px 이상만 되도) 필요한 소수점 정밀도가 2 이하로 낮아진다.

이제 작업이 완료된 아트웍의 코드를 복사해서 SVGMO 사이트에서 Inline SVG의 코드 길이를 더 줄일 수 있는지 확인한다. 이 사이트를 이용하면 피그마에서 복사해온 SVG 코드에 대한 소수점 정밀도도 수정할 수 있다.

SVGMO 사이트의 우측 설정 항목에서 Global Settings의 4개 항목만 꺼놓고 진행하면 된다. 필자가 사용하는 설정이 필요하다면 여기를 클릭한다.

코드를 붙여 넣을때는 사이트 좌측 상단 메뉴 아이콘을 열어 Paste Markup을 클릭하고 붙여 넣으면 된다.

테스트 방법은 간단하다. 우측 사이드 바의 Precision 슬라이더를 좌로 옮기면 소수점 정밀도가 떨어지는데, 아트웍이 눈에 띄게 변형되지 않는 선에서 최대 1까지 내려본다.
0까지도 내릴 수 있으나 안전장치의 의미로 1까지만 내리도록 한다.

Show Original 버튼을 토글해 보면서 원본과 현재 상태를 비교한다. 만일 정밀도 1에서도 시각적으로 큰 손실이 없다면 그대로 우측 최하단의 복사 아이콘으로 코드를 복사해 프로젝트에 붙여 넣는다.

정밀도를 수정한 SVG 코드가 애니메이션에 의해 크기가 변하게 될 경우에도 시각적 문제가 없는지 반드시 확인한다.

				
					// 노드 정리 안함
<path d="M135.416,241.152l-2.913-1.082C42.472,206.602,5.314,142.31,.561,93.301-2.863,58.004,9.531,28.094,33.713,13.291c15.421-9.438,48.777-20.117,101.28,11.672C184.493-9.361,217.162-.919,232.448,7.397c24.193,13.162,37.444,42.071,35.446,77.331-1.624,28.658-13.459,58.747-33.324,84.725-22.848,29.877-56.139,54.267-96.274,70.532l-2.88,1.167ZM69.664,19.615c-10.304,0-19.597,2.425-27.597,7.322-18.836,11.53-28.399,35.761-25.581,64.819,4.236,43.671,37.682,101.052,118.68,132.214,82.104-34.355,114.181-94.733,116.755-140.147,1.639-28.925-8.499-52.241-27.119-62.371-21.433-11.662-51.547-4.706-84.792,19.579l-4.418,3.228-4.61-2.948c-22.493-14.383-43.428-21.695-61.318-21.695Z"/>

// Simplify와 Pen 툴 병행 후 소수점 정밀도 조정
<path d="M134.8 241C-63 172.5-25.9-68.1 134.4 24.9c152.4-102.4 199.4 139.3.4 216.1Zm-.2-17.2c169.5-66.4 140.6-284.7.4-179.7-139.6-95.2-177.5 111.4-.4 179.7Z"/>
				
			

어트리뷰트 개선

마지막으로, SVG 태그에 포함되는 각종 어트리뷰트(xmln, xml:space, version 따위)의 생략 가능 여부를 알아보고 최종 코드를 완성한다.

XML 관련 규약 명시 및 Attribute

				
					<!DOCTYPE svg PUBLIC 
  "-//W3C//DTD SVG 1.1//EN" 
  "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<?xml version="1.0" encoding="UTF-8"?>
<svg 
  version="1.1" 
  xmlns="http://www.w3.org/2000/svg" 
  xmlns:xlink="http://www.w3.org/1999/xlink" 
  xml:space="preserve">
  ...
</svg>
				
			

SVG는 XML 기반 마크업 언어이며, XML은 <SVG>와 같은 태그 이름을 사용자가 직접 정의해 사용할 수 있다.
때문에 네이밍 충돌 방지를 위해 xmlns 처럼 특수한 어트리뷰트가 명시되어야 브라우저가 이를 제대로 파싱하고 렌더링하게 된다.

다만 HTML5를 Doctype으로 갖는 문서 상에서 코드를 직접 삽입하는 Inline SVG 경우 대부분의 XML 관련 규약 및 어트리뷰트를 생략할 수 있다.

				
					<svg width="320" height="320" viewBox="0 0 320 320">
  ...
</svg>
				
			

SVG를 파일로 저장하여 image / svg + xml 또는 application / xhtml + xml 처럼 사용자 에이전트가 XML 파서를 사용하게하는 MIME 유형으로 사용하는 경우, 파일의 코드 안에 xmlns 어트리뷰트 만큼은 반드시 명시해야하며, 그렇지 않으면 이미지가 표시되지 않는다.

				
					<svg xmlns="http://www.w3.org/2000/svg" width="320" height="320" viewBox="0 0 320 320">
  ...
</svg>
				
			
				
					// xmlns 어트리뷰트 명시가 필요한 경우의 예

<img src="test.svg">

<embed type="image/svg+xml" src="test.svg">

<object type="image/svg+xml" data="test.svg"></object>

<iframe src="test.svg"></iframe>
				
			

width, height 어트리뷰트

				
					<svg width="320" height="320" viewBox="0 0 320 320">
  ...
</svg>
				
			

너비와 높이에 관련된 어트리뷰트를 제거하면 별도의 CSS 스타일링이 명시되어 있지 않는 한 이미지가 브라우저의 뷰포트 너비를 꽉 채운다.
별도의 스타일링을 거치거나 부모 요소의 크기에 동적으로 맞추려는 경우는 생략한다.

마치며

				
					<svg width="320" height="320" viewBox="0 0 320 320">
  <path d="M134.8 241C-63 172.5-25.9-68.1 134.4 24.9c152.4-102.4 199.4 139.3.4 216.1Zm-.2-17.2c169.5-66.4 140.6-284.7.4-179.7-139.6-95.2-177.5 111.4-.4 179.7Z"/>
</svg>
				
			

하트 모양의 아트웍으로 시작한 SVG의 최종 인라인 코드는 위와 같다.

단순한 조형이라도 그래픽 에디터의 Boolean, Path Finder에 의한 연산 또는 Outline Stroke, Create Ouline 등의 명령에 의해 불필요한 앵커 포인트가 발생하기 마련이다.

시간적 여유가 있다면 직접 노드를 정리해 보는 시간을 가져보길 바란다.

목록으로 돌아가려면 화면 하단 X 버튼 클릭