이미지 최적화
메인급 서비스들을 개발하면서 느낀 점 중 하나는 생각보다 이미지 파일들이 많이 필요하다. 주로 간단한 아이콘들이 많다.
많은 아이콘들을 간단하게 관리를 하기 위해서는 여러가지 방법이 있다. 대표적으로 이미지 스프라이트 기법을 주로 사용하는 것 같았다.
그런데 담당님께서 아이콘들을 전부 SVG로 추출해서 URL 인코딩을 하시고 SCSS 파일에 넣으셨다.
왜 이렇게 번거러운 작업을 하시는지 궁금해서 혼자 이것저것 찾아보면서 공부를 하다가 이유를 찾았다.
아마, 이미지 최적화 때문이지 않을까 생각한다.
새로고침 시 이미지는 계속 불러와 지는데, SVG를 인코딩 하는 방식은 Data URI로 변경을 하면 브라우저에 캐싱이 되어 새로고침 시
크기와 시간을 줄여 이미지 최적화를 할 수 있다.
SVG를 인코딩하여 Data URI를 만드는 과정을 하나씩 공부해봤다.
아이콘 PNG → SVG → URL 인코딩 SVG
1. Figma에서 SVG로 Export

주의 사항 : 아이콘들이 ‘면’ 으로 되어있어야 한다.
이유 : SVG 장점 중 하나는 CSS로 색상, 크기 등을 쉽게 변경할 수 있다. 아이콘들의 색상을 쉽게 변경을 하려면 fill 속성을
사용하기 때문에 ‘선’ 으로 되어있는 아이콘들은 Outline stroke, 윤곽선 만들기로 변경하고 그래도 안되는 경우는 디자이너에게 요청하였다.

2. 확장자 .svg로 다운받아진 파일을 메모장이나 편집 가능한 곳에서 열기 후 불필요한 내용 수정
- fill로 설정되어 있는 것들은 다 지워주면 된다.

3. SVG 코드들을 encoded
- URL-encoder for SVG 사이트 애용.
4. Insert SVG에 <svg></svg>를 먼저 작성 후 메모장에 <svg> 태그를 제외하고 복사 + 붙여넣기
- Preview에서 잘 변환 되었는지 확인을 꼼꼼히 해준다.

5. Take encoded 에 있는 코드 복사하기
6. SCSS 변수를 지정해서 사용할 클래스명을 key 값으로, encoded 된 코드들은 value 값으로 지정
1 | |
변환 끝
HOW? : 사용 방법
사용하기 전에 어떻게 아이콘이 보여진다는건지 원리를 알고 싶었다.
문자 조합 함수
1 | |
str-replace ( $string, $search, $replace )
- 용도 : 문자 값의 일부를 다른 문자 값으로 대체하는 SCSS 내장 함수
- 매개변수 : 함수에 변경할 문자, 찾을 문자, 변경할 문자

str-index ( $string, $substring )

- 용도 : $string 내에서 $substring의 첫 번째 인덱스를 반환. 포함하지 않으면 null 반환

str-slice ( $string, $start-at, $end-at )

- 용도 : $string에서 $start-at 인덱스에서 시작하여 $end-at 인덱스에서 끝나는 (양쪽 모두 포함) 부분 반환

str-length ( $string )

- 용도 : $string에 있는 문자의 수를 반환

아이콘 Data URI 조합 함수
1 | |
map-get ($map, $key, $keys… )

- 용도 : $map 안에 있는 $key의 value 값을 반환, 없으면 null 반환

$result: $result + “%3Cg fill=’“+str-replace(‘’+ $color, ‘#’, ‘%23’)+”‘%3E”;
- SVG 코드에서 fill=”#000000” 을 URL 인코딩 시키면 fill=’%23000000’ 이런식으로 HTML 태그의 ‘<’, ’>’, ’#’ 같은 문자가 URL 인코딩 방식으로 변환된다.
1
2
3'<' === '%3c' '>' === '%3E' '#' === '%23'
str-replace(‘’+ $color, ‘#’, ‘%23’)
- 이부분은 ‘#’을 ‘%23’으로 바꾸기 위한 작업.
$color → #000000 으로 가정하면,
- ‘’ + $color : 이 표현식은 SCSS에서 ‘#000000’을 문자열로 취급하기 위해 빈문자열 ‘’ 을 더한 것.
- str-replace(‘#000000’, ‘#’, ‘%23’) $string → ‘#000000’ $search → ‘#’ $replace → ‘%23’
- str-index(’#000000’, ‘#’) $index → 1
- str-slice(’#000000’, 1, 0) → 빈문자열 ‘ ’
- str-slice(’#000000’, 1 + str-length(‘#’)) str-length(‘#’)) → 1 str-slice(’#000000’, 2) → 000000
- str-replce(’000000’, ‘#’, ‘%23’) $string → ‘000000’ $search → ‘#’ $replace → ‘%23’
- str-index(’000000’, ‘#’) $index → null
- @if $index → 조건이 false 일 때 재귀 호출이 종료
- str-slice($string, 1, $index - 1) → ‘ ‘ $replace → %23 str-replace(str-slice($string, $index + str-length($search)), $search, $replace) → 000000 ’’+%23+000000
- @return → ‘%23000000’
1 | |
WHY? : 왜 이렇게 사용하는지
- 이미지가 많다면 이미지의 용량을 줄이고 유지보수를 위해서는 다양한 방법이 있다. 대표적으로는 이미지 스트라이프 기법도 있는데, 왜 굳이 이렇게 사용하는지 궁금해서 몇가지 생각해보고 찾아보았다.
SVG 코드 장단점
장점
- 파일 크기 감소
SVG 코드는 텍스트 형식이므로 일반적으로 크기가 작아 페이지 로딩 속도가 빨라질 수 있음. - 확장성
SVG는 백터 형식. 해상도에 상관없이 이미지사 선명하게 유지. 반응형에 유리. - 스타일
CSS를 사용하여 SVG의 색상, 크기 등을 쉽게 변경 가능 - 적은 HTTP 요청
이미지를 직접 코드에 포함시킴으로써 추가적인 HTTP 요청을 줄일 수 있어 성능 향상 - DOM 내에서 조작 용이
SVG는 DOM의 일부로 취급. JS를 통해 동적으로 수정하거나 애니메이션 적용 용이
단점
- HTML이나 CSS 파일 복잡
- 데이터 보안 이슈
외부에서 제공받은 SVG 코드는 보안문제가 생길 수 있음
이미지 파일 장단점
장점
- 일반적인 사용
대부분 개발자가 사용할 수 있어서 급할때는 변경이 가능 - 복잡한 그래픽 표현
- 이미지 파일이 별도로 관리되므로 명확한 파일 관리
단점
- 해상도 제약
비트맵 형식인 PNG, JPG는 고해상도로 확대 시 깨질 수 있음. - 파일 크기 증가
고해상도 이미지는 파일 크기가 커져 페이지 로딩 속도를 저하 - 반응형 제약
결론
- SVG 코드 → 주로 아이콘이나 간단한 그래픽을 사용할 때 유리. 반응형 디자인이나 스타일 변경이 필요한 경우 적합
- 이미지 파일 → 복잡한 그래픽이나 사진과 같이 정교한 이미지 표현이 필요할 때 유용